Changeset 0.22.7 (#149)

This commit is contained in:
2026-03-04 10:44:42 +00:00
parent d8e0664fa3
commit 389e47b0f9
62 changed files with 6820 additions and 1476 deletions

View File

@@ -265,13 +265,13 @@ func (h *OpenRouterHooks) PostStreamEvent(_ ProviderConfig, _ *StreamEvent) {
// No post-processing needed. OpenRouter returns standard OAI format.
}
// ── Preset Override Merge ───────────────────
// ── Persona Override Merge ───────────────────
// MergePresetSettings merges persona-level setting overrides onto
// provider-level settings. Preset values take priority except for
// MergePersonaSettings merges persona-level setting overrides onto
// provider-level settings. Persona values take priority except for
// fields marked ProviderOnly in the schema.
func MergePresetSettings(providerType string, providerSettings, presetOverrides map[string]interface{}) map[string]interface{} {
if len(presetOverrides) == 0 {
func MergePersonaSettings(providerType string, providerSettings, personaOverrides map[string]interface{}) map[string]interface{} {
if len(personaOverrides) == 0 {
return providerSettings
}
@@ -283,11 +283,11 @@ func MergePresetSettings(providerType string, providerSettings, presetOverrides
}
}
merged := make(map[string]interface{}, len(providerSettings)+len(presetOverrides))
merged := make(map[string]interface{}, len(providerSettings)+len(personaOverrides))
for k, v := range providerSettings {
merged[k] = v
}
for k, v := range presetOverrides {
for k, v := range personaOverrides {
if !providerOnly[k] {
merged[k] = v
}

View File

@@ -270,45 +270,45 @@ func TestGetHooks_Unknown(t *testing.T) {
}
}
// ── MergePresetSettings Tests ──────────────
// ── MergePersonaSettings Tests ──────────────
func TestMergePresetSettings_Basic(t *testing.T) {
func TestMergePersonaSettings_Basic(t *testing.T) {
provider := map[string]interface{}{
"system_prompt_prefix": "Provider prompt",
"frequency_penalty": 0.3,
}
preset := map[string]interface{}{
"system_prompt_prefix": "Preset prompt",
persona := map[string]interface{}{
"system_prompt_prefix": "Persona prompt",
}
merged := MergePresetSettings("openai", provider, preset)
merged := MergePersonaSettings("openai", provider, persona)
if merged["system_prompt_prefix"] != "Preset prompt" {
t.Errorf("preset should override provider, got %v", merged["system_prompt_prefix"])
if merged["system_prompt_prefix"] != "Persona prompt" {
t.Errorf("persona should override provider, got %v", merged["system_prompt_prefix"])
}
if merged["frequency_penalty"] != 0.3 {
t.Errorf("provider value should be preserved, got %v", merged["frequency_penalty"])
}
}
func TestMergePresetSettings_ProviderOnlyBlocked(t *testing.T) {
func TestMergePersonaSettings_ProviderOnlyBlocked(t *testing.T) {
provider := map[string]interface{}{
"route": "auto",
}
preset := map[string]interface{}{
persona := map[string]interface{}{
"route": "fallback", // route is ProviderOnly for openrouter
}
merged := MergePresetSettings("openrouter", provider, preset)
merged := MergePersonaSettings("openrouter", provider, persona)
if merged["route"] != "auto" {
t.Errorf("ProviderOnly field should not be overridden by preset, got %v", merged["route"])
t.Errorf("ProviderOnly field should not be overridden by persona, got %v", merged["route"])
}
}
func TestMergePresetSettings_EmptyOverrides(t *testing.T) {
func TestMergePersonaSettings_EmptyOverrides(t *testing.T) {
provider := map[string]interface{}{"key": "value"}
merged := MergePresetSettings("openai", provider, nil)
merged := MergePersonaSettings("openai", provider, nil)
if merged["key"] != "value" {
t.Error("empty overrides should return provider settings unchanged")
}

View File

@@ -18,7 +18,7 @@ type ProfileField struct {
Min *int `json:"min,omitempty"` // min for int/float
Max *int `json:"max,omitempty"` // max for int/float
DependsOn string `json:"depends_on,omitempty"` // only show when this key is truthy
ProviderOnly bool `json:"provider_only,omitempty"` // not overridable at preset level
ProviderOnly bool `json:"provider_only,omitempty"` // not overridable at persona level
}
// ── Built-in Profile Schemas ────────────────