Files
2026-08-29 11:55:38 +03:00

42 lines
1.8 KiB
Go

package domain
import (
"fmt"
"git.cin.su/m/Assistant/contracts/configuration"
"sort"
)
var ErrInvalidConfigurationCommand = fmt.Errorf("invalid conversational configuration command")
func Resolve(definition configuration.SettingDefinition, assignments []configuration.SettingAssignment, selector configuration.ScopeSelector) (configuration.EffectiveSetting, error) {
if err := definition.Validate(); err != nil {
return configuration.EffectiveSetting{}, err
}
var matches []configuration.SettingAssignment
for _, a := range assignments {
if err := a.Validate(); err != nil {
return configuration.EffectiveSetting{}, err
}
if a.DefinitionRef == string(definition.ID) && a.Lifecycle == configuration.SettingActive && a.Selector.PrincipalRef == selector.PrincipalRef && a.Selector.SkillRef == selector.SkillRef {
matches = append(matches, a)
}
}
if len(matches) == 0 {
return configuration.EffectiveSetting{DefinitionRef: string(definition.ID), Value: definition.DefaultValue, ResolutionTrace: []string{"system-default"}}, nil
}
sort.SliceStable(matches, func(i, j int) bool { return specificity(matches[i].Selector) > specificity(matches[j].Selector) })
if len(matches) > 1 && specificity(matches[0].Selector) == specificity(matches[1].Selector) {
return configuration.EffectiveSetting{}, fmt.Errorf("configuration conflict")
}
return configuration.EffectiveSetting{DefinitionRef: string(definition.ID), Value: matches[0].TypedValue, WinningAssignmentRef: string(matches[0].ID), ResolutionTrace: []string{"specificity-selected"}}, nil
}
func specificity(s configuration.ScopeSelector) int {
return len(s.RequiredContextBindings) + boolInt(s.SkillRef != "") + boolInt(s.TaskRef != "") + boolInt(s.SessionRef != "") + boolInt(s.TemporaryOverride)
}
func boolInt(v bool) int {
if v {
return 1
}
return 0
}