Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,57 @@ public interface AgentSkillRepository extends AutoCloseable {
*/
boolean isWriteable();

/**
* Reads a single raw file under a skill directory.
*
* <p>For filesystem-backed repositories, this reads a file from the skill's
* directory on disk. For database-backed repositories, this may retrieve
* a skill resource stored as a BLOB or text column.
*
* <p>The default implementation returns {@code null} — callers should check
* the return value and handle unsupported operations gracefully.
*
* @param skillName The skill name (never null)
* @param relPath The relative path within the skill directory (e.g. "SKILL.md",
* "references/api.md")
* @return The file content, or {@code null} if the file does not exist or the
* operation is not supported by this repository implementation
*/
default String readSkillFile(String skillName, String relPath) {
return null;
}

/**
* Writes a single raw file under a skill directory.
*
* <p>The default implementation returns {@code false} — callers should check
* the return value and handle unsupported operations gracefully.
*
* @param skillName The skill name
* @param relPath The relative path within the skill directory
* @param content The file content to write
* @return {@code true} if the write succeeded, {@code false} otherwise
*/
default boolean writeSkillFile(String skillName, String relPath, String content) {
return false;
}

/**
* Deletes a single raw file under a skill directory.
*
* <p>Idempotent: implementations should return {@code true} for missing files.
* The default implementation returns {@code false} — callers should check
* the return value and handle unsupported operations gracefully.
*
* @param skillName The skill name
* @param relPath The relative path within the skill directory
* @return {@code true} if the delete succeeded (or file was already missing),
* {@code false} if the operation is not supported
*/
default boolean deleteSkillFile(String skillName, String relPath) {
return false;
}

/**
* Cleans up any resources used by this repository.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import io.agentscope.core.skill.util.SkillUtil;
import io.agentscope.core.tool.AgentTool;
import io.agentscope.core.tool.ToolCallParam;
import io.agentscope.harness.agent.skill.WorkspaceSkillRepository;
import io.agentscope.core.skill.repository.AgentSkillRepository;
import io.agentscope.harness.agent.skill.curator.SkillAuditLog;
import io.agentscope.harness.agent.skill.curator.SkillSecurityScanner;
import io.agentscope.harness.agent.skill.curator.SkillUsageRecord;
Expand Down Expand Up @@ -73,10 +73,10 @@ public class SkillManageTool implements AgentTool {
Set.of("references", "templates", "scripts", "assets");

/** Repository pointing at the live skills root (e.g. {@code skills/}). */
private final WorkspaceSkillRepository mainRepo;
private final AgentSkillRepository mainRepo;

/** Repository pointing at the draft staging dir (e.g. {@code skills/_drafts/}). */
private final WorkspaceSkillRepository draftsRepo;
private final AgentSkillRepository draftsRepo;

/** Optional telemetry sidecar; null disables provenance + counter writes. */
private final SkillUsageStore usageStore;
Expand All @@ -87,23 +87,23 @@ public class SkillManageTool implements AgentTool {
private final SkillManageConfig config;

public SkillManageTool(
WorkspaceSkillRepository mainRepo,
WorkspaceSkillRepository draftsRepo,
AgentSkillRepository mainRepo,
AgentSkillRepository draftsRepo,
SkillManageConfig config) {
this(mainRepo, draftsRepo, config, null, null);
}

public SkillManageTool(
WorkspaceSkillRepository mainRepo,
WorkspaceSkillRepository draftsRepo,
AgentSkillRepository mainRepo,
AgentSkillRepository draftsRepo,
SkillManageConfig config,
SkillUsageStore usageStore) {
this(mainRepo, draftsRepo, config, usageStore, null);
}

public SkillManageTool(
WorkspaceSkillRepository mainRepo,
WorkspaceSkillRepository draftsRepo,
AgentSkillRepository mainRepo,
AgentSkillRepository draftsRepo,
SkillManageConfig config,
SkillUsageStore usageStore,
SkillAuditLog auditLog) {
Expand Down Expand Up @@ -330,7 +330,7 @@ private ToolResultBlock doCreate(String name, String content, String sessionId)
"Description exceeds " + MAX_DESCRIPTION_LENGTH + " chars.");
}

WorkspaceSkillRepository target = config.autoPromote() ? mainRepo : draftsRepo;
AgentSkillRepository target = config.autoPromote() ? mainRepo : draftsRepo;
boolean ok = target.save(List.of(skill), false);
if (!ok) {
return ToolResultBlock.error(
Expand Down Expand Up @@ -393,7 +393,7 @@ private ToolResultBlock doEdit(String name, String content) {
if (contentErr != null) {
return ToolResultBlock.error(contentErr);
}
WorkspaceSkillRepository target = locate(name);
AgentSkillRepository target = locate(name);
if (target == null) {
return ToolResultBlock.error("Skill '" + name + "' not found.");
}
Expand Down Expand Up @@ -441,7 +441,7 @@ private ToolResultBlock doPatch(
return ToolResultBlock.error(
"Missing 'new_string' for patch (use empty string to delete matched text).");
}
WorkspaceSkillRepository target = locate(name);
AgentSkillRepository target = locate(name);
if (target == null) {
return ToolResultBlock.error("Skill '" + name + "' not found.");
}
Expand Down Expand Up @@ -562,7 +562,7 @@ private ToolResultBlock doWriteFile(String name, String filePath, String fileCon
return ToolResultBlock.error(
"file_content exceeds " + MAX_SKILL_FILE_BYTES + " bytes.");
}
WorkspaceSkillRepository target = locate(name);
AgentSkillRepository target = locate(name);
if (target == null) {
return ToolResultBlock.error("Skill '" + name + "' not found.");
}
Expand Down Expand Up @@ -600,7 +600,7 @@ private ToolResultBlock doRemoveFile(String name, String filePath) {
if (filePathErr != null) {
return ToolResultBlock.error(filePathErr);
}
WorkspaceSkillRepository target = locate(name);
AgentSkillRepository target = locate(name);
if (target == null) {
return ToolResultBlock.error("Skill '" + name + "' not found.");
}
Expand All @@ -613,7 +613,7 @@ private ToolResultBlock doRemoveFile(String name, String filePath) {
}

private ToolResultBlock doDelete(String name, String absorbedInto) {
WorkspaceSkillRepository target = locate(name);
AgentSkillRepository target = locate(name);
if (target == null) {
return ToolResultBlock.error("Skill '" + name + "' not found.");
}
Expand Down Expand Up @@ -671,7 +671,7 @@ private void bumpPatchSilent(String name) {
}

/** Locate the repository that owns a skill by name; drafts win on collision. */
private WorkspaceSkillRepository locate(String name) {
private AgentSkillRepository locate(String name) {
if (draftsRepo.skillExists(name)) {
return draftsRepo;
}
Expand Down
Loading