Files
goaiapi/src/go/pluginsdk/manifest.go
2026-06-03 14:09:58 +08:00

67 lines
2.2 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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,
}
}