142 lines
3.2 KiB
Go
142 lines
3.2 KiB
Go
package adapters
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"go.uber.org/zap"
|
|
"google.golang.org/protobuf/types/known/structpb"
|
|
|
|
"iop/apps/node/internal/adapters/cli"
|
|
"iop/apps/node/internal/adapters/mock"
|
|
"iop/apps/node/internal/adapters/ollama"
|
|
"iop/apps/node/internal/adapters/vllm"
|
|
"iop/packages/config"
|
|
iop "iop/proto/gen/iop"
|
|
)
|
|
|
|
// BuildFromPayload creates a Registry from a NodeConfigPayload received from edge.
|
|
func BuildFromPayload(payload *iop.NodeConfigPayload, logger *zap.Logger) (*Registry, error) {
|
|
reg := NewRegistry()
|
|
reg.Register(mock.New(logger))
|
|
|
|
for _, ac := range payload.GetAdapters() {
|
|
if !ac.GetEnabled() {
|
|
continue
|
|
}
|
|
switch ac.GetType() {
|
|
case "mock":
|
|
// mock is always registered above.
|
|
case "ollama":
|
|
cfg := ollamaConfFromStruct(ac.GetSettings())
|
|
reg.Register(ollama.New(cfg, logger))
|
|
case "vllm":
|
|
cfg := vllmConfFromStruct(ac.GetSettings())
|
|
reg.Register(vllm.New(cfg, logger))
|
|
case "cli":
|
|
cfg := cliConfFromStruct(ac.GetSettings())
|
|
reg.Register(cli.New(cfg, logger))
|
|
default:
|
|
return nil, fmt.Errorf("adapters: unknown adapter type %q", ac.GetType())
|
|
}
|
|
}
|
|
return reg, nil
|
|
}
|
|
|
|
func ollamaConfFromStruct(s *structpb.Struct) config.OllamaConf {
|
|
if s == nil {
|
|
return config.OllamaConf{}
|
|
}
|
|
m := s.AsMap()
|
|
cfg := config.OllamaConf{Enabled: true}
|
|
if v, ok := m["base_url"].(string); ok {
|
|
cfg.BaseURL = v
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func vllmConfFromStruct(s *structpb.Struct) config.VllmConf {
|
|
if s == nil {
|
|
return config.VllmConf{}
|
|
}
|
|
m := s.AsMap()
|
|
cfg := config.VllmConf{Enabled: true}
|
|
if v, ok := m["endpoint"].(string); ok {
|
|
cfg.Endpoint = v
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func cliConfFromStruct(s *structpb.Struct) config.CLIConf {
|
|
if s == nil {
|
|
return config.CLIConf{}
|
|
}
|
|
m := s.AsMap()
|
|
cfg := config.CLIConf{Enabled: true, Profiles: make(map[string]config.CLIProfileConf)}
|
|
if profiles, ok := m["profiles"].(map[string]any); ok {
|
|
for name, pAny := range profiles {
|
|
p, ok := pAny.(map[string]any)
|
|
if !ok {
|
|
continue
|
|
}
|
|
prof := config.CLIProfileConf{}
|
|
if cmd, ok := p["command"].(string); ok {
|
|
prof.Command = cmd
|
|
}
|
|
if args, ok := p["args"].([]any); ok {
|
|
for _, a := range args {
|
|
if s, ok := a.(string); ok {
|
|
prof.Args = append(prof.Args, s)
|
|
}
|
|
}
|
|
}
|
|
if envs, ok := p["env"].([]any); ok {
|
|
for _, e := range envs {
|
|
if s, ok := e.(string); ok {
|
|
prof.Env = append(prof.Env, s)
|
|
}
|
|
}
|
|
}
|
|
if v, ok := boolFromAny(p["persistent"]); ok {
|
|
prof.Persistent = v
|
|
}
|
|
if v, ok := boolFromAny(p["terminal"]); ok {
|
|
prof.Terminal = v
|
|
}
|
|
if v, ok := intFromAny(p["response_idle_timeout_ms"]); ok {
|
|
prof.ResponseIdleTimeoutMS = v
|
|
}
|
|
if v, ok := intFromAny(p["startup_idle_timeout_ms"]); ok {
|
|
prof.StartupIdleTimeoutMS = v
|
|
}
|
|
if v, ok := p["output_format"].(string); ok {
|
|
prof.OutputFormat = v
|
|
}
|
|
cfg.Profiles[name] = prof
|
|
}
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func boolFromAny(v any) (bool, bool) {
|
|
if v == nil {
|
|
return false, false
|
|
}
|
|
if b, ok := v.(bool); ok {
|
|
return b, true
|
|
}
|
|
return false, false
|
|
}
|
|
|
|
func intFromAny(v any) (int, bool) {
|
|
if v == nil {
|
|
return 0, false
|
|
}
|
|
// structpb encodes numbers as float64
|
|
if f, ok := v.(float64); ok {
|
|
return int(f), true
|
|
}
|
|
if i, ok := v.(int); ok {
|
|
return i, true
|
|
}
|
|
return 0, false
|
|
}
|