19fb5f35e9
Add setParamsByID filter that applies different request parameters based
on the requested model ID, enabling per-alias behaviour for a single
loaded model.
- add SetParamsByID field to Filters struct and SanitizedSetParamsByID
method
- substitute ${MODEL_ID} and other macros in setParamsByID keys and
values
- validate no unknown macros remain in keys or values after substitution
- apply setParamsByID in proxyInferenceHandler after setParams (can
override it)
- update config-schema.json with setParamsByID definition
- update UI to show aliases and make them selectable in the Playground
closes #534
173 lines
4.8 KiB
Go
173 lines
4.8 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestConfig_ModelConfigSanitizedCommand(t *testing.T) {
|
|
config := &ModelConfig{
|
|
Cmd: `python model1.py \
|
|
--arg1 value1 \
|
|
--arg2 value2`,
|
|
}
|
|
|
|
args, err := config.SanitizedCommand()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []string{"python", "model1.py", "--arg1", "value1", "--arg2", "value2"}, args)
|
|
}
|
|
|
|
func TestConfig_ModelFilters(t *testing.T) {
|
|
content := `
|
|
macros:
|
|
default_strip: "temperature, top_p"
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
# macros inserted and list is cleaned of duplicates and empty strings
|
|
stripParams: "model, top_k, top_k, temperature, ${default_strip}, , ,"
|
|
# check for strip_params (legacy field name) compatibility
|
|
legacy:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
strip_params: "model, top_k, top_k, temperature, ${default_strip}, , ,"
|
|
`
|
|
config, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.NoError(t, err)
|
|
for modelId, modelConfig := range config.Models {
|
|
t.Run(fmt.Sprintf("Testing macros in filters for model %s", modelId), func(t *testing.T) {
|
|
assert.Equal(t, "model, top_k, top_k, temperature, temperature, top_p, , ,", modelConfig.Filters.StripParams)
|
|
sanitized, err := modelConfig.Filters.SanitizedStripParams()
|
|
if assert.NoError(t, err) {
|
|
// model has been removed
|
|
// empty strings have been removed
|
|
// duplicates have been removed
|
|
assert.Equal(t, []string{"temperature", "top_k", "top_p"}, sanitized)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestConfig_ModelSendLoadingState(t *testing.T) {
|
|
content := `
|
|
sendLoadingState: true
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
sendLoadingState: false
|
|
model2:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
`
|
|
config, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.NoError(t, err)
|
|
assert.True(t, config.SendLoadingState)
|
|
if assert.NotNil(t, config.Models["model1"].SendLoadingState) {
|
|
assert.False(t, *config.Models["model1"].SendLoadingState)
|
|
}
|
|
if assert.NotNil(t, config.Models["model2"].SendLoadingState) {
|
|
assert.True(t, *config.Models["model2"].SendLoadingState)
|
|
}
|
|
}
|
|
|
|
func TestConfig_SetParamsByIDAutoAlias(t *testing.T) {
|
|
content := `
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
setParamsByID:
|
|
"${MODEL_ID}:high":
|
|
reasoning_effort: high
|
|
"${MODEL_ID}:low":
|
|
reasoning_effort: low
|
|
`
|
|
cfg, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.NoError(t, err)
|
|
|
|
// Keys (other than the model's own ID) should be registered as aliases
|
|
realName, found := cfg.RealModelName("model1:high")
|
|
assert.True(t, found, "model1:high should be an auto-registered alias")
|
|
assert.Equal(t, "model1", realName)
|
|
|
|
realName, found = cfg.RealModelName("model1:low")
|
|
assert.True(t, found, "model1:low should be an auto-registered alias")
|
|
assert.Equal(t, "model1", realName)
|
|
|
|
// Auto-aliases should also appear in modelConfig.Aliases
|
|
aliases := cfg.Models["model1"].Aliases
|
|
assert.Contains(t, aliases, "model1:high")
|
|
assert.Contains(t, aliases, "model1:low")
|
|
}
|
|
|
|
func TestConfig_SetParamsByIDAutoAliasConflictWithModelID(t *testing.T) {
|
|
content := `
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
setParamsByID:
|
|
model2:
|
|
reasoning_effort: high
|
|
model2:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
`
|
|
_, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.ErrorContains(t, err, "conflicts with an existing model ID")
|
|
}
|
|
|
|
func TestConfig_SetParamsByIDAutoAliasConflictWithOtherModel(t *testing.T) {
|
|
content := `
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
setParamsByID:
|
|
"shared-alias":
|
|
reasoning_effort: high
|
|
model2:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
setParamsByID:
|
|
"shared-alias":
|
|
reasoning_effort: low
|
|
`
|
|
_, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.ErrorContains(t, err, "duplicate alias")
|
|
}
|
|
|
|
func TestConfig_ModelFiltersWithSetParams(t *testing.T) {
|
|
content := `
|
|
models:
|
|
model1:
|
|
cmd: path/to/cmd --port ${PORT}
|
|
filters:
|
|
stripParams: "top_k"
|
|
setParams:
|
|
temperature: 0.7
|
|
top_p: 0.9
|
|
stop:
|
|
- "<|end|>"
|
|
- "<|stop|>"
|
|
`
|
|
config, err := LoadConfigFromReader(strings.NewReader(content))
|
|
assert.NoError(t, err)
|
|
|
|
modelConfig := config.Models["model1"]
|
|
|
|
// Check stripParams
|
|
stripParams, err := modelConfig.Filters.SanitizedStripParams()
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, []string{"top_k"}, stripParams)
|
|
|
|
// Check setParams
|
|
setParams, keys := modelConfig.Filters.SanitizedSetParams()
|
|
assert.NotNil(t, setParams)
|
|
assert.Equal(t, []string{"stop", "temperature", "top_p"}, keys)
|
|
assert.Equal(t, 0.7, setParams["temperature"])
|
|
assert.Equal(t, 0.9, setParams["top_p"])
|
|
}
|