This commit is contained in:
2026-06-03 14:09:58 +08:00
parent ddd9d43f9d
commit 2b456dbb07
46 changed files with 7145 additions and 1422 deletions

View File

@@ -0,0 +1,66 @@
package pluginsdk
import (
"fmt"
"github.com/Masterminds/semver/v3"
contractv1 "goaiapi/proto/contract/v1"
)
// ComputeTier 由依赖图复算层级——不信插件自报,内核以此校验声明。
// 无依赖 -> base
// 只依赖 base -> mid
// 依赖任一非 base -> complex
// allTiers 是「已注册插件名 -> 其层级」的快照。
func ComputeTier(deps []Dependency, allTiers map[string]contractv1.PluginTier) contractv1.PluginTier {
if len(deps) == 0 {
return contractv1.PluginTier_TIER_BASE
}
for _, d := range deps {
t, ok := allTiers[d.Name]
if !ok || t != contractv1.PluginTier_TIER_BASE {
// 依赖未知(尚未注册)或依赖非 base都算 complex
return contractv1.PluginTier_TIER_COMPLEX
}
}
return contractv1.PluginTier_TIER_MID
}
// ValidateManifest 校验 manifest 自洽:名字/版本非空、版本是合法 semver、
// 依赖约束可解析。tier 的 DAG 一致性由内核在注册时校验(这里拿不到全图)。
func ValidateManifest(m Manifest) error {
if m.Name == "" {
return fmt.Errorf("插件名为空")
}
if _, err := semver.NewVersion(m.Version); err != nil {
return fmt.Errorf("插件 %s 版本号 %q 非合法 semver: %w", m.Name, m.Version, err)
}
for _, d := range m.Dependencies {
if d.Name == "" {
return fmt.Errorf("插件 %s 有一条依赖名为空", m.Name)
}
if _, err := semver.NewConstraint(d.VersionConstraint); err != nil {
return fmt.Errorf("插件 %s 依赖 %s 的约束 %q 非法: %w",
m.Name, d.Name, d.VersionConstraint, err)
}
}
return nil
}
// toProto 把 SDK 的 Manifest 转成 GetManifest 响应。
func (m Manifest) toProto() *contractv1.GetManifestResponse {
deps := make([]*contractv1.Dependency, 0, len(m.Dependencies))
for _, d := range m.Dependencies {
deps = append(deps, &contractv1.Dependency{
Name: d.Name,
VersionConstraint: d.VersionConstraint,
})
}
caps := make([]*contractv1.Capability, 0, len(m.Capabilities))
for _, c := range m.Capabilities {
caps = append(caps, &contractv1.Capability{ServiceName: c})
}
return &contractv1.GetManifestResponse{
Name: m.Name, Version: m.Version, Tier: m.Tier, Deps: deps, Caps: caps,
}
}