feat: 完善标准 Skill 包底座
- 标准化 SKILL.md、资源模型、校验规则与安全限额 - 支持流式内容存储和单、多 Skill ZIP 双向编解码
This commit is contained in:
@@ -1,20 +1,59 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
import com.easyagents.skill.exception.SkillPackageException;
|
||||
import com.easyagents.skill.model.Skill;
|
||||
import com.easyagents.skill.model.SkillPackage;
|
||||
import com.easyagents.skill.model.SkillPackageLayout;
|
||||
import com.easyagents.skill.validation.SkillValidationReport;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Skill 包导入接口。
|
||||
* Skill 包双向流式编解码接口。
|
||||
*/
|
||||
public interface SkillPackageCodec {
|
||||
|
||||
/**
|
||||
* 从 zip 输入流导入 Skill。
|
||||
* 从 ZIP 输入流导入 Skill。
|
||||
*
|
||||
* @param inputStream zip 输入流
|
||||
* @param inputStream ZIP 输入流
|
||||
* @return Skill 列表
|
||||
* @throws SkillPackageException ZIP 结构、内容或安全校验失败
|
||||
* @deprecated 请使用 {@link #decode(InputStream, SkillPackageReadOptions)} 获取包形态、hash 和诊断。
|
||||
*/
|
||||
@Deprecated
|
||||
List<Skill> importZip(InputStream inputStream);
|
||||
|
||||
/**
|
||||
* 解码 Skill ZIP。
|
||||
*
|
||||
* <p>兼容默认实现委托旧导入接口;正式 Codec 应覆盖。</p>
|
||||
*
|
||||
* @param inputStream ZIP 输入流
|
||||
* @param options 读取选项
|
||||
* @return 解码结果
|
||||
* @throws SkillPackageException ZIP 结构、内容、安全校验或资源存储失败
|
||||
*/
|
||||
default SkillPackageReadResult decode(InputStream inputStream, SkillPackageReadOptions options) {
|
||||
List<Skill> skills = importZip(inputStream);
|
||||
SkillPackageLayout layout = skills.size() > 1
|
||||
? SkillPackageLayout.MULTI_DIRECTORY : SkillPackageLayout.SINGLE_DIRECTORY;
|
||||
return new SkillPackageReadResult(new SkillPackage(layout, skills), new SkillValidationReport(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
* 将 Skill 包编码为标准 ZIP。
|
||||
*
|
||||
* @param skillPackage Skill 包
|
||||
* @param outputStream 输出流,不由本方法关闭
|
||||
* @param options 写出选项
|
||||
* @return 编码结果
|
||||
* @throws SkillPackageException Skill 包不合法、资源不可读或 ZIP 写出失败
|
||||
*/
|
||||
default SkillPackageWriteResult encode(SkillPackage skillPackage, OutputStream outputStream,
|
||||
SkillPackageWriteOptions options) {
|
||||
throw new SkillPackageException("This SkillPackageCodec does not support encoding.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
/**
|
||||
* Skill 包读取后的内容处理模式。
|
||||
*/
|
||||
public enum SkillPackageReadMode {
|
||||
|
||||
/**
|
||||
* 校验通过后提交二进制内容;校验失败时抛出异常并回滚暂存内容。
|
||||
*/
|
||||
COMMIT_ON_VALID,
|
||||
|
||||
/**
|
||||
* 返回可解析包的完整校验报告并回滚全部暂存内容,不提交二进制内容。
|
||||
* 返回资源中的 contentRef 仅表示内容哈希身份,不保证读取结果返回后仍可打开。
|
||||
*/
|
||||
REPORT_ONLY
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
import com.easyagents.skill.model.SkillPackageLimits;
|
||||
|
||||
/**
|
||||
* Skill 包读取选项。
|
||||
*/
|
||||
public final class SkillPackageReadOptions {
|
||||
|
||||
private final SkillPackageLimits limits;
|
||||
private final SkillPackageReadMode mode;
|
||||
|
||||
/**
|
||||
* 使用指定安全限额创建读取选项。
|
||||
*
|
||||
* @param limits 安全限额
|
||||
*/
|
||||
public SkillPackageReadOptions(SkillPackageLimits limits) {
|
||||
this(limits, SkillPackageReadMode.COMMIT_ON_VALID);
|
||||
}
|
||||
|
||||
/**
|
||||
* 使用指定安全限额和内容处理模式创建读取选项。
|
||||
*
|
||||
* @param limits 安全限额
|
||||
* @param mode 内容处理模式
|
||||
*/
|
||||
public SkillPackageReadOptions(SkillPackageLimits limits, SkillPackageReadMode mode) {
|
||||
this.limits = limits == null ? SkillPackageLimits.defaults() : limits;
|
||||
this.mode = mode == null ? SkillPackageReadMode.COMMIT_ON_VALID : mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认读取选项。
|
||||
*
|
||||
* @return 默认读取选项
|
||||
*/
|
||||
public static SkillPackageReadOptions defaults() {
|
||||
return new SkillPackageReadOptions(SkillPackageLimits.defaults());
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建只返回校验报告且不提交内容的读取选项。
|
||||
* 二进制资源的 contentRef 仅表示内容哈希身份,不承诺可通过内容存储打开。
|
||||
*
|
||||
* @return 只读预检选项
|
||||
*/
|
||||
public static SkillPackageReadOptions reportOnly() {
|
||||
return new SkillPackageReadOptions(SkillPackageLimits.defaults(), SkillPackageReadMode.REPORT_ONLY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取安全限额。
|
||||
*
|
||||
* @return 安全限额
|
||||
*/
|
||||
public SkillPackageLimits getLimits() {
|
||||
return limits;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取内容处理模式。
|
||||
*
|
||||
* @return 内容处理模式
|
||||
*/
|
||||
public SkillPackageReadMode getMode() {
|
||||
return mode;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
import com.easyagents.skill.model.SkillPackage;
|
||||
import com.easyagents.skill.validation.SkillValidationReport;
|
||||
|
||||
/**
|
||||
* Skill 包解码结果。
|
||||
*/
|
||||
public final class SkillPackageReadResult {
|
||||
|
||||
private final SkillPackage skillPackage;
|
||||
private final SkillValidationReport validationReport;
|
||||
private final String packageHash;
|
||||
|
||||
/**
|
||||
* 创建解码结果。
|
||||
*
|
||||
* @param skillPackage Skill 包
|
||||
* @param validationReport 校验报告
|
||||
* @param packageHash 输入 ZIP SHA-256
|
||||
*/
|
||||
public SkillPackageReadResult(SkillPackage skillPackage, SkillValidationReport validationReport,
|
||||
String packageHash) {
|
||||
this.skillPackage = skillPackage;
|
||||
this.validationReport = validationReport;
|
||||
this.packageHash = packageHash;
|
||||
}
|
||||
|
||||
/** @return Skill 包 */
|
||||
public SkillPackage getSkillPackage() {
|
||||
return skillPackage;
|
||||
}
|
||||
|
||||
/** @return 结构化校验报告 */
|
||||
public SkillValidationReport getValidationReport() {
|
||||
return validationReport;
|
||||
}
|
||||
|
||||
/** @return 输入 ZIP SHA-256 */
|
||||
public String getPackageHash() {
|
||||
return packageHash;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
import com.easyagents.skill.model.SkillPackageLimits;
|
||||
|
||||
/**
|
||||
* Skill 包写出选项。
|
||||
*/
|
||||
public final class SkillPackageWriteOptions {
|
||||
|
||||
private final SkillPackageLimits limits;
|
||||
|
||||
/**
|
||||
* 使用指定安全限额创建写出选项。
|
||||
*
|
||||
* @param limits 安全限额
|
||||
*/
|
||||
public SkillPackageWriteOptions(SkillPackageLimits limits) {
|
||||
this.limits = limits == null ? SkillPackageLimits.defaults() : limits;
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建默认写出选项。
|
||||
*
|
||||
* @return 默认写出选项
|
||||
*/
|
||||
public static SkillPackageWriteOptions defaults() {
|
||||
return new SkillPackageWriteOptions(SkillPackageLimits.defaults());
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取安全限额。
|
||||
*
|
||||
* @return 安全限额
|
||||
*/
|
||||
public SkillPackageLimits getLimits() {
|
||||
return limits;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
package com.easyagents.skill.codec;
|
||||
|
||||
import com.easyagents.skill.model.SkillPackageLayout;
|
||||
|
||||
/**
|
||||
* Skill 包编码结果。
|
||||
*/
|
||||
public final class SkillPackageWriteResult {
|
||||
|
||||
private final String packageHash;
|
||||
private final long size;
|
||||
private final int entryCount;
|
||||
private final SkillPackageLayout layout;
|
||||
|
||||
/**
|
||||
* 创建编码结果。
|
||||
*
|
||||
* @param packageHash 输出 ZIP SHA-256
|
||||
* @param size 输出字节数
|
||||
* @param entryCount 输出 entry 数
|
||||
*/
|
||||
public SkillPackageWriteResult(String packageHash, long size, int entryCount) {
|
||||
this(packageHash, size, entryCount, SkillPackageLayout.SINGLE_DIRECTORY);
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建带包形态的编码结果。
|
||||
*
|
||||
* @param packageHash 输出 ZIP SHA-256
|
||||
* @param size 输出字节数
|
||||
* @param entryCount 输出 entry 数
|
||||
* @param layout 输出包形态
|
||||
*/
|
||||
public SkillPackageWriteResult(String packageHash, long size, int entryCount,
|
||||
SkillPackageLayout layout) {
|
||||
this.packageHash = packageHash;
|
||||
this.size = size;
|
||||
this.entryCount = entryCount;
|
||||
this.layout = layout == null ? SkillPackageLayout.SINGLE_DIRECTORY : layout;
|
||||
}
|
||||
|
||||
/** @return 输出 ZIP SHA-256 */
|
||||
public String getPackageHash() {
|
||||
return packageHash;
|
||||
}
|
||||
|
||||
/** @return 输出字节数 */
|
||||
public long getSize() {
|
||||
return size;
|
||||
}
|
||||
|
||||
/** @return 输出 entry 数 */
|
||||
public int getEntryCount() {
|
||||
return entryCount;
|
||||
}
|
||||
|
||||
/** @return 输出包形态 */
|
||||
public SkillPackageLayout getLayout() {
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user