- Migrate config contract files to archive (01_config_contract) - Update edge config.go for new configuration structure - Refactor node/mapper.go and mapper_test.go for field mapping - Update node/store_test.go tests - Add new fields to configs/edge.yaml - Extend packages/go/config with new configuration options - Update protobuf definitions in runtime.proto and generated code
147 lines
4.3 KiB
Go
147 lines
4.3 KiB
Go
package node
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"iop/packages/go/config"
|
|
iop "iop/proto/gen/iop"
|
|
)
|
|
|
|
// BuildConfigPayload converts a NodeRecord's adapter config to the proto payload
|
|
// sent to node during registration.
|
|
//
|
|
// After config normalisation, OllamaInstances, VllmInstances, and
|
|
// OpenAICompatInstances already contain the promoted legacy single-instance
|
|
// entries, so only the slice fields are iterated here. Duplicate instance names
|
|
// produce an error.
|
|
func BuildConfigPayload(rec *NodeRecord) (*iop.NodeConfigPayload, error) {
|
|
payload := &iop.NodeConfigPayload{
|
|
Runtime: &iop.NodeRuntimeConfig{
|
|
Concurrency: int32(rec.Runtime.Concurrency),
|
|
WorkspaceRoot: rec.Runtime.WorkspaceRoot,
|
|
},
|
|
}
|
|
|
|
payload.Adapters = append(payload.Adapters, &iop.AdapterConfig{
|
|
Type: "mock",
|
|
Enabled: true,
|
|
Config: &iop.AdapterConfig_Mock{Mock: &iop.MockAdapterConfig{}},
|
|
})
|
|
|
|
seen := make(map[string]struct{})
|
|
|
|
for _, inst := range rec.Adapters.OllamaInstances {
|
|
if !inst.Enabled {
|
|
continue
|
|
}
|
|
key := "ollama:" + inst.Name
|
|
if _, dup := seen[key]; dup {
|
|
return nil, fmt.Errorf("duplicate ollama instance name %q", inst.Name)
|
|
}
|
|
seen[key] = struct{}{}
|
|
payload.Adapters = append(payload.Adapters, &iop.AdapterConfig{
|
|
Type: "ollama",
|
|
Enabled: true,
|
|
Name: inst.Name,
|
|
Config: &iop.AdapterConfig_Ollama{
|
|
Ollama: &iop.OllamaAdapterConfig{
|
|
BaseUrl: inst.BaseURL,
|
|
ContextSize: int32(inst.ContextSize),
|
|
Capacity: int32(inst.Capacity),
|
|
MaxQueue: int32(inst.MaxQueue),
|
|
QueueTimeoutMs: int32(inst.QueueTimeoutMS),
|
|
RequestTimeoutMs: int32(inst.RequestTimeoutMS),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
for _, inst := range rec.Adapters.VllmInstances {
|
|
if !inst.Enabled {
|
|
continue
|
|
}
|
|
key := "vllm:" + inst.Name
|
|
if _, dup := seen[key]; dup {
|
|
return nil, fmt.Errorf("duplicate vllm instance name %q", inst.Name)
|
|
}
|
|
seen[key] = struct{}{}
|
|
payload.Adapters = append(payload.Adapters, &iop.AdapterConfig{
|
|
Type: "vllm",
|
|
Enabled: true,
|
|
Name: inst.Name,
|
|
Config: &iop.AdapterConfig_Vllm{
|
|
Vllm: &iop.VllmAdapterConfig{
|
|
Endpoint: inst.Endpoint,
|
|
Capacity: int32(inst.Capacity),
|
|
MaxQueue: int32(inst.MaxQueue),
|
|
QueueTimeoutMs: int32(inst.QueueTimeoutMS),
|
|
RequestTimeoutMs: int32(inst.RequestTimeoutMS),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
for _, inst := range rec.Adapters.OpenAICompatInstances {
|
|
if !inst.Enabled {
|
|
continue
|
|
}
|
|
key := "openai_compat:" + inst.Name
|
|
if _, dup := seen[key]; dup {
|
|
return nil, fmt.Errorf("duplicate openai_compat instance name %q", inst.Name)
|
|
}
|
|
seen[key] = struct{}{}
|
|
payload.Adapters = append(payload.Adapters, &iop.AdapterConfig{
|
|
Type: "openai_compat",
|
|
Enabled: true,
|
|
Name: inst.Name,
|
|
Config: &iop.AdapterConfig_OpenaiCompat{
|
|
OpenaiCompat: &iop.OpenAICompatAdapterConfig{
|
|
Provider: inst.Provider,
|
|
Endpoint: inst.Endpoint,
|
|
Headers: inst.Headers,
|
|
Capacity: int32(inst.Capacity),
|
|
MaxQueue: int32(inst.MaxQueue),
|
|
QueueTimeoutMs: int32(inst.QueueTimeoutMS),
|
|
RequestTimeoutMs: int32(inst.RequestTimeoutMS),
|
|
},
|
|
},
|
|
})
|
|
}
|
|
|
|
if rec.Adapters.CLI.Enabled {
|
|
profiles := make(map[string]*iop.CLIProfileConfig, len(rec.Adapters.CLI.Profiles))
|
|
for name, p := range rec.Adapters.CLI.Profiles {
|
|
profiles[name] = cliProfileToProto(p)
|
|
}
|
|
payload.Adapters = append(payload.Adapters, &iop.AdapterConfig{
|
|
Type: "cli",
|
|
Enabled: true,
|
|
Config: &iop.AdapterConfig_Cli{
|
|
Cli: &iop.CLIAdapterConfig{Profiles: profiles},
|
|
},
|
|
})
|
|
}
|
|
return payload, nil
|
|
}
|
|
|
|
func cliProfileToProto(p config.CLIProfileConf) *iop.CLIProfileConfig {
|
|
out := &iop.CLIProfileConfig{
|
|
Command: p.Command,
|
|
Args: append([]string(nil), p.Args...),
|
|
Env: append([]string(nil), p.Env...),
|
|
Persistent: p.Persistent,
|
|
Terminal: p.Terminal,
|
|
ResponseIdleTimeoutMs: int32(p.ResponseIdleTimeoutMS),
|
|
StartupIdleTimeoutMs: int32(p.StartupIdleTimeoutMS),
|
|
OutputFormat: p.OutputFormat,
|
|
Mode: p.Mode,
|
|
ResumeArgs: append([]string(nil), p.ResumeArgs...),
|
|
}
|
|
if !p.CompletionMarker.Empty() {
|
|
out.CompletionMarker = &iop.CLICompletionMarker{
|
|
Line: p.CompletionMarker.Line,
|
|
Regex: p.CompletionMarker.Regex,
|
|
}
|
|
}
|
|
return out
|
|
}
|