-
Notifications
You must be signed in to change notification settings - Fork 361
Add NacosSkillRepository #902
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
11 commits
Select commit
Hold shift + click to select a range
cd1caa7
add nacos skill repository
qiacheng7 080ba89
Merge branch 'agentscope-ai:main' into main
qiacheng7 a66e7f3
add nacos skill repository
qiacheng7 288b2af
add nacos skill repository
qiacheng7 e64dfb9
edit pom
qiacheng7 b66477f
edit pom
qiacheng7 b47ec4d
set mvnd --no-daemon
qiacheng7 d392351
delete mvnd --no-daemon
qiacheng7 70569b0
add agent-skill.md
qiacheng7 fc6f591
modify according to copilot's recommendations
qiacheng7 488c337
modify according to copilot's recommendations
qiacheng7 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
47 changes: 47 additions & 0 deletions
47
agentscope-extensions/agentscope-extensions-nacos/agentscope-extensions-nacos-skill/pom.xml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!-- | ||
| ~ Copyright 2024-2026 the original author or authors. | ||
| ~ | ||
| ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
| ~ you may not use this file except in compliance with the License. | ||
| ~ You may obtain a copy of the License at | ||
| ~ | ||
| ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
| ~ | ||
| ~ Unless required by applicable law or agreed to in writing, software | ||
| ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
| ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| ~ See the License for the specific language governing permissions and | ||
| ~ limitations under the License. | ||
| --> | ||
|
|
||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
| <parent> | ||
| <groupId>io.agentscope</groupId> | ||
| <artifactId>agentscope-extensions-nacos</artifactId> | ||
| <version>${revision}</version> | ||
| <relativePath>../pom.xml</relativePath> | ||
| </parent> | ||
|
|
||
| <artifactId>agentscope-extensions-nacos-skill</artifactId> | ||
| <name>AgentScope Java - Nacos Skill Repository</name> | ||
| <description>agentscope-extensions-nacos-skill</description> | ||
|
|
||
| <dependencies> | ||
| <!-- Core library is needed at runtime for AgentSkillRepository, AgentSkill, etc. --> | ||
| <dependency> | ||
| <groupId>io.agentscope</groupId> | ||
| <artifactId>agentscope-core</artifactId> | ||
| </dependency> | ||
|
|
||
| <dependency> | ||
| <groupId>com.alibaba.nacos</groupId> | ||
| <artifactId>nacos-client</artifactId> | ||
| </dependency> | ||
|
|
||
| </dependencies> | ||
|
|
||
| </project> |
155 changes: 155 additions & 0 deletions
155
...nsions-nacos-skill/src/main/java/io/agentscope/core/nacos/skill/NacosSkillRepository.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,155 @@ | ||
| /* | ||
| * Copyright 2024-2026 the original author or authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.agentscope.core.nacos.skill; | ||
|
|
||
| import com.alibaba.nacos.api.ai.AiService; | ||
| import com.alibaba.nacos.api.ai.model.skills.Skill; | ||
| import com.alibaba.nacos.api.exception.NacosException; | ||
| import com.alibaba.nacos.common.utils.StringUtils; | ||
| import io.agentscope.core.skill.AgentSkill; | ||
| import io.agentscope.core.skill.repository.AgentSkillRepository; | ||
| import io.agentscope.core.skill.repository.AgentSkillRepositoryInfo; | ||
| import java.util.Collections; | ||
| import java.util.List; | ||
| import org.slf4j.Logger; | ||
| import org.slf4j.LoggerFactory; | ||
|
|
||
| /** | ||
| * Nacos-based implementation of {@link AgentSkillRepository}. | ||
| * | ||
| * <p>Reads skills from Nacos Config via {@code AiService.loadSkill(String)}. This implementation | ||
| * supports read operations: {@link #getSkill(String)}, {@link #skillExists(String)}, {@link | ||
| * #getRepositoryInfo()}, {@link #getSource()}, and {@link #isWriteable()}. List and write | ||
| * operations ({@link #getAllSkillNames()}, {@link #getAllSkills()}, {@link #save(List, boolean)}, | ||
| * {@link #delete(String)}) | ||
| * are implemented as read-only no-ops: they return empty list or {@code false} and log a warning. | ||
| */ | ||
| public class NacosSkillRepository implements AgentSkillRepository { | ||
|
|
||
| private static final Logger log = LoggerFactory.getLogger(NacosSkillRepository.class); | ||
|
|
||
| private static final String REPO_TYPE = "nacos"; | ||
| private static final String LOCATION_PREFIX = "namespace:"; | ||
|
|
||
| private final AiService aiService; | ||
| private final String namespaceId; | ||
| private final String source; | ||
| private final String location; | ||
|
|
||
| /** | ||
| * Creates a Nacos skill repository. | ||
| * | ||
| * @param aiService the Nacos AI service (must not be null) | ||
| * @param namespaceId the Nacos namespace ID (null or blank is treated as default namespace) | ||
| */ | ||
| public NacosSkillRepository(AiService aiService, String namespaceId) { | ||
| if (aiService == null) { | ||
| throw new IllegalArgumentException("AiService cannot be null"); | ||
| } | ||
| this.aiService = aiService; | ||
| this.namespaceId = StringUtils.isBlank(namespaceId) ? "public" : namespaceId.trim(); | ||
| this.source = REPO_TYPE + ":" + this.namespaceId; | ||
| this.location = LOCATION_PREFIX + this.namespaceId; | ||
| log.info("NacosSkillRepository initialized for namespace: {}", this.namespaceId); | ||
| } | ||
|
|
||
| @Override | ||
| public AgentSkill getSkill(String name) { | ||
| if (name == null || name.isBlank()) { | ||
| throw new IllegalArgumentException("Skill name cannot be null or empty"); | ||
| } | ||
| try { | ||
| Skill nacosSkill = aiService.loadSkill(name.trim()); | ||
| if (nacosSkill == null) { | ||
| throw new IllegalArgumentException("Skill not found: " + name); | ||
| } | ||
| return NacosSkillToAgentSkillConverter.toAgentSkill(nacosSkill, getSource()); | ||
| } catch (NacosException e) { | ||
| if (e.getErrCode() == NacosException.NOT_FOUND) { | ||
| throw new IllegalArgumentException("Skill not found: " + name, e); | ||
| } | ||
| throw new RuntimeException("Failed to load skill from Nacos: " + name, e); | ||
| } | ||
| } | ||
qiacheng7 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| @Override | ||
| public boolean skillExists(String skillName) { | ||
| if (skillName == null || skillName.isBlank()) { | ||
| return false; | ||
| } | ||
| try { | ||
| Skill skill = aiService.loadSkill(skillName.trim()); | ||
| return skill != null; | ||
| } catch (NacosException e) { | ||
| if (e.getErrCode() == NacosException.NOT_FOUND) { | ||
| return false; | ||
| } | ||
| log.warn("Error checking skill existence for {}: {}", skillName, e.getMessage()); | ||
| return false; | ||
| } | ||
| } | ||
|
|
||
| @Override | ||
| public AgentSkillRepositoryInfo getRepositoryInfo() { | ||
| return new AgentSkillRepositoryInfo(REPO_TYPE, location, false); | ||
| } | ||
|
|
||
| @Override | ||
| public String getSource() { | ||
| return source; | ||
| } | ||
|
|
||
| @Override | ||
| public void setWriteable(boolean writeable) { | ||
| log.warn("NacosSkillRepository is read-only, set writeable operation ignored"); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean isWriteable() { | ||
| return false; | ||
| } | ||
|
|
||
| // ---------- Read-only no-op operations (list and write) ---------- | ||
|
|
||
| @Override | ||
| public List<String> getAllSkillNames() { | ||
| log.warn("NacosSkillRepository is read-only, getAllSkillNames returns empty list"); | ||
| return Collections.emptyList(); | ||
| } | ||
|
|
||
| @Override | ||
| public List<AgentSkill> getAllSkills() { | ||
| log.warn("NacosSkillRepository is read-only, getAllSkills returns empty list"); | ||
| return Collections.emptyList(); | ||
| } | ||
|
|
||
| @Override | ||
| public boolean save(List<AgentSkill> skills, boolean force) { | ||
| log.warn("NacosSkillRepository is read-only, save operation ignored"); | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public boolean delete(String skillName) { | ||
| log.warn("NacosSkillRepository is read-only, delete operation ignored"); | ||
| return false; | ||
| } | ||
|
|
||
| @Override | ||
| public void close() { | ||
| // AiService lifecycle is managed by the caller; nothing to release here | ||
| } | ||
| } | ||
69 changes: 69 additions & 0 deletions
69
...s-skill/src/main/java/io/agentscope/core/nacos/skill/NacosSkillToAgentSkillConverter.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| /* | ||
| * Copyright 2024-2026 the original author or authors. | ||
| * | ||
| * Licensed under the Apache License, Version 2.0 (the "License"); | ||
| * you may not use this file except in compliance with the License. | ||
| * You may obtain a copy of the License at | ||
| * | ||
| * http://www.apache.org/licenses/LICENSE-2.0 | ||
| * | ||
| * Unless required by applicable law or agreed to in writing, software | ||
| * distributed under the License is distributed on an "AS IS" BASIS, | ||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| * See the License for the specific language governing permissions and | ||
| * limitations under the License. | ||
| */ | ||
| package io.agentscope.core.nacos.skill; | ||
|
|
||
| import com.alibaba.nacos.api.ai.model.skills.Skill; | ||
| import com.alibaba.nacos.api.ai.model.skills.SkillResource; | ||
| import io.agentscope.core.skill.AgentSkill; | ||
| import java.util.HashMap; | ||
| import java.util.Map; | ||
|
|
||
| /** | ||
| * Converts Nacos AI {@link Skill} to AgentScope {@link AgentSkill}. | ||
| */ | ||
| public final class NacosSkillToAgentSkillConverter { | ||
|
|
||
| private static final String NO_DESCRIPTION = "(no description)"; | ||
| private static final String NO_INSTRUCTION = "(no instruction)"; | ||
|
|
||
| private NacosSkillToAgentSkillConverter() {} | ||
|
|
||
| /** | ||
| * Converts a Nacos Skill to an AgentSkill. | ||
| * | ||
| * @param nacosSkill the Nacos Skill (must not be null) | ||
| * @param source the source identifier for the resulting AgentSkill (e.g. "nacos:public") | ||
| * @return the converted AgentSkill | ||
| */ | ||
| public static AgentSkill toAgentSkill(Skill nacosSkill, String source) { | ||
| if (nacosSkill == null) { | ||
| throw new IllegalArgumentException("Nacos Skill cannot be null"); | ||
| } | ||
| String name = blankToDefault(nacosSkill.getName(), "unknown"); | ||
| String description = blankToDefault(nacosSkill.getDescription(), NO_DESCRIPTION); | ||
| String skillContent = blankToDefault(nacosSkill.getInstruction(), NO_INSTRUCTION); | ||
| Map<String, String> resources = toResourceMap(nacosSkill.getResource()); | ||
| return new AgentSkill(name, description, skillContent, resources, source); | ||
| } | ||
|
|
||
| private static String blankToDefault(String value, String defaultValue) { | ||
| return (value != null && !value.isBlank()) ? value.trim() : defaultValue; | ||
| } | ||
|
|
||
| private static Map<String, String> toResourceMap(Map<String, SkillResource> resourceMap) { | ||
| if (resourceMap == null || resourceMap.isEmpty()) { | ||
| return new HashMap<>(); | ||
| } | ||
| Map<String, String> result = new HashMap<>(resourceMap.size()); | ||
| for (Map.Entry<String, SkillResource> e : resourceMap.entrySet()) { | ||
| String key = e.getKey() != null ? e.getKey() : "resource"; | ||
| SkillResource res = e.getValue(); | ||
| String content = (res != null && res.getContent() != null) ? res.getContent() : ""; | ||
| result.put(key, content); | ||
| } | ||
| return result; | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.