iop/apps/node/internal/adapters/factory.go

204 lines
5.3 KiB
Go

package adapters
import (
"go.uber.org/zap"
"google.golang.org/protobuf/types/known/structpb"
"iop/packages/go/config"
runtime "iop/packages/go/execution"
iop "iop/proto/gen/iop"
)
// BuildFromPayload creates a Registry from a NodeConfigPayload received from edge.
func BuildFromPayload(payload *iop.NodeConfigPayload, logger *zap.Logger) (*runtime.Registry, error) {
set, err := BuildConfigSet(payload, logger)
if err != nil {
return nil, err
}
return set.Registry, nil
}
func ollamaConfFromProto(m *iop.OllamaAdapterConfig) config.OllamaConf {
return config.OllamaConf{
Enabled: true,
BaseURL: m.GetBaseUrl(),
ContextSize: int(m.GetContextSize()),
Capacity: int(m.GetCapacity()),
MaxQueue: int(m.GetMaxQueue()),
QueueTimeoutMS: int(m.GetQueueTimeoutMs()),
RequestTimeoutMS: int(m.GetRequestTimeoutMs()),
}
}
func vllmConfFromProto(m *iop.VllmAdapterConfig) config.VllmConf {
return config.VllmConf{
Enabled: true,
Endpoint: m.GetEndpoint(),
Capacity: int(m.GetCapacity()),
MaxQueue: int(m.GetMaxQueue()),
QueueTimeoutMS: int(m.GetQueueTimeoutMs()),
RequestTimeoutMS: int(m.GetRequestTimeoutMs()),
}
}
func openAICompatConfFromProto(m *iop.OpenAICompatAdapterConfig) config.OpenAICompatConf {
return config.OpenAICompatConf{
Enabled: true,
Provider: m.GetProvider(),
Endpoint: m.GetEndpoint(),
Headers: m.GetHeaders(),
Capacity: int(m.GetCapacity()),
MaxQueue: int(m.GetMaxQueue()),
QueueTimeoutMS: int(m.GetQueueTimeoutMs()),
RequestTimeoutMS: int(m.GetRequestTimeoutMs()),
RuntimeProfile: concreteProfileFromProto(m.GetProtocolProfile()),
}
}
// concreteProfileFromProto converts a wire ConcreteProtocolProfile to the
// runtime config snapshot. Returns nil when the profile is absent so legacy
// payloads without a profile remain source-compatible.
func concreteProfileFromProto(m *iop.ConcreteProtocolProfile) *config.ConcreteProtocolProfile {
if m == nil {
return nil
}
cp := &config.ConcreteProtocolProfile{
ID: m.GetId(),
ProtocolProfileConf: config.ProtocolProfileConf{
Driver: config.ProtocolDriver(m.GetDriver()),
BaseURL: m.GetBaseUrl(),
Auth: config.ProtocolAuthConf{
Header: m.GetAuth().GetHeader(),
Scheme: m.GetAuth().GetScheme(),
},
Capabilities: append([]string(nil), m.GetCapabilities()...),
},
}
if len(m.GetOperations()) > 0 {
cp.Operations = make(map[string]string, len(m.GetOperations()))
for k, v := range m.GetOperations() {
cp.Operations[k] = v
}
}
if len(m.GetModelMapping()) > 0 {
cp.ModelMapping = make(map[string]string, len(m.GetModelMapping()))
for k, v := range m.GetModelMapping() {
cp.ModelMapping[k] = v
}
}
if m.GetExtensions() != nil {
cp.Extensions = m.GetExtensions().AsMap()
}
cloned := cp.Clone()
return &cloned
}
// Legacy structpb fallback paths for payloads from older edge versions
// that populate AdapterConfig.settings instead of the typed oneof.
func ollamaConfFromStruct(s *structpb.Struct) config.OllamaConf {
cfg := config.OllamaConf{Enabled: true}
if s == nil {
return cfg
}
m := s.AsMap()
if v, ok := m["base_url"].(string); ok {
cfg.BaseURL = v
}
if v, ok := intSetting(m, "context_size"); ok {
cfg.ContextSize = v
} else if v, ok := intSetting(m, "num_ctx"); ok {
cfg.ContextSize = v
}
if v, ok := intSetting(m, "capacity"); ok {
cfg.Capacity = v
}
if v, ok := intSetting(m, "max_queue"); ok {
cfg.MaxQueue = v
}
if v, ok := intSetting(m, "queue_timeout_ms"); ok {
cfg.QueueTimeoutMS = v
}
if v, ok := intSetting(m, "request_timeout_ms"); ok {
cfg.RequestTimeoutMS = v
}
return cfg
}
func intSetting(m map[string]any, key string) (int, bool) {
v, ok := m[key]
if !ok {
return 0, false
}
switch n := v.(type) {
case int:
return n, true
case int32:
return int(n), true
case int64:
return int(n), true
case float64:
return int(n), true
default:
return 0, false
}
}
func vllmConfFromStruct(s *structpb.Struct) config.VllmConf {
cfg := config.VllmConf{Enabled: true}
if s == nil {
return cfg
}
m := s.AsMap()
if v, ok := m["endpoint"].(string); ok {
cfg.Endpoint = v
}
if v, ok := intSetting(m, "capacity"); ok {
cfg.Capacity = v
}
if v, ok := intSetting(m, "max_queue"); ok {
cfg.MaxQueue = v
}
if v, ok := intSetting(m, "queue_timeout_ms"); ok {
cfg.QueueTimeoutMS = v
}
if v, ok := intSetting(m, "request_timeout_ms"); ok {
cfg.RequestTimeoutMS = v
}
return cfg
}
func openAICompatConfFromStruct(s *structpb.Struct) config.OpenAICompatConf {
cfg := config.OpenAICompatConf{Enabled: true}
if s == nil {
return cfg
}
m := s.AsMap()
if v, ok := m["provider"].(string); ok {
cfg.Provider = v
}
if v, ok := m["endpoint"].(string); ok {
cfg.Endpoint = v
}
if headers, ok := m["headers"].(map[string]any); ok {
cfg.Headers = make(map[string]string, len(headers))
for k, hv := range headers {
if s, ok := hv.(string); ok {
cfg.Headers[k] = s
}
}
}
if v, ok := intSetting(m, "capacity"); ok {
cfg.Capacity = v
}
if v, ok := intSetting(m, "max_queue"); ok {
cfg.MaxQueue = v
}
if v, ok := intSetting(m, "queue_timeout_ms"); ok {
cfg.QueueTimeoutMS = v
}
if v, ok := intSetting(m, "request_timeout_ms"); ok {
cfg.RequestTimeoutMS = v
}
return cfg
}