package model_runtime import ( "embed" "encoding/json" "fmt" "strings" "github.com/APIParkLab/APIPark/gateway" "github.com/eolinker/eosc" ) func init() { Load() } type IConfig interface { Check(cfg string) error GenConfig(target string, origin string) (string, error) DefaultConfig() string } func NewConfig(cfg string, validator IParamValidator) *Config { return &Config{cfg: cfg, validator: validator} } type Config struct { cfg string validator IParamValidator } func (c *Config) Check(cfg string) error { data := make(map[string]interface{}) err := json.Unmarshal([]byte(cfg), &data) if err != nil { return err } return c.validator.Valid(data) } func (c *Config) GenConfig(target string, origin string) (string, error) { var targetData map[string]interface{} err := json.Unmarshal([]byte(target), &targetData) if err != nil { return "", err } var originData map[string]interface{} err = json.Unmarshal([]byte(origin), &originData) if err != nil { return "", err } return c.validator.GenConfig(targetData, originData) } func (c *Config) DefaultConfig() string { return c.cfg } const ( DirAssets = "assets" ) var ( //go:embed model-providers/* providerDir embed.FS ) func Load() error { files, err := providerDir.ReadDir("model-providers") if err != nil { return err } for _, file := range files { if !file.IsDir() { continue } name := fmt.Sprintf("model-providers/%s", file.Name()) err = LoadProvider(name) if err != nil { return err } } return nil } func LoadProvider(name string) error { files, err := providerDir.ReadDir(name) if err != nil { return err } var providerFile string models := make(map[string]eosc.Untyped[string, string]) for _, file := range files { if file.IsDir() { result, err := ReadFile(providerDir, fmt.Sprintf("%s/%s", name, file.Name())) if err != nil { return err } models[file.Name()] = result continue } if strings.HasSuffix(file.Name(), ".yaml") { data, err := providerDir.ReadFile(fmt.Sprintf("%s/%s", name, file.Name())) if err != nil { return err } providerFile = string(data) } } provider, err := NewProvider(providerFile, models) if err != nil { return err } gateway.RegisterDynamicResourceDriver(provider.ID(), gateway.Worker{ Profession: gateway.ProfessionAIProvider, Driver: provider.ID(), }) Register(provider.ID(), provider) return nil } func ReadFile(dir embed.FS, name string) (eosc.Untyped[string, string], error) { files, err := dir.ReadDir(name) if err != nil { return nil, err } result := eosc.BuildUntyped[string, string]() for _, file := range files { if file.IsDir() { continue } if !strings.HasSuffix(file.Name(), ".yaml") && !strings.HasSuffix(file.Name(), ".svg") { continue } data, err := dir.ReadFile(fmt.Sprintf("%s/%s", name, file.Name())) if err != nil { return nil, fmt.Errorf("open file %s error: %w", file.Name(), err) } result.Set(file.Name(), string(data)) } return result, nil }