Skip to content

Commit 9b7d7fd

Browse files
grasbergclaude
andcommitted
fix: merge default model catalog into existing configs on load
Previously LoadConfig replaced the default catalog entirely when a user's config.json already had model_list entries. This meant catalog updates in new releases were silently ignored for existing users. mergeCatalogEntries() now runs after every config load: it appends any catalog entry whose model_name isn't already in the user's list. User entries are never overwritten, nothing is removed — the merge is purely additive. New catalog entries become visible on next restart. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
1 parent 5023ee9 commit 9b7d7fd

2 files changed

Lines changed: 26 additions & 3 deletions

File tree

pkg/config/config.go

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,9 @@ type GuardrailsConfig struct {
108108

109109
// CircuitBreakerConfig configures the circuit breaker for tool calls.
110110
type CircuitBreakerConfig struct {
111-
Enabled bool `json:"enabled" env:"SOFIA_GUARDRAILS_CB_ENABLED"`
112-
FailureThreshold int `json:"failure_threshold" env:"SOFIA_GUARDRAILS_CB_THRESHOLD"`
113-
CooldownPeriod time.Duration `json:"cooldown_period" env:"SOFIA_GUARDRAILS_CB_COOLDOWN"`
111+
Enabled bool `json:"enabled" env:"SOFIA_GUARDRAILS_CB_ENABLED"`
112+
FailureThreshold int `json:"failure_threshold" env:"SOFIA_GUARDRAILS_CB_THRESHOLD"`
113+
CooldownPeriod time.Duration `json:"cooldown_period" env:"SOFIA_GUARDRAILS_CB_COOLDOWN"`
114114
}
115115

116116
// ApprovalConfig defines which tool calls require human-in-the-loop approval.
@@ -120,6 +120,7 @@ type ApprovalConfig struct {
120120
PatternMatch []string `json:"pattern_match"` // regex patterns on tool args
121121
TimeoutSec int `json:"timeout_sec"` // how long to wait (default 300)
122122
DefaultAction string `json:"default_action"` // "deny" or "allow" on timeout
123+
GooseMode string `json:"goose_mode"` // "auto", "approve", "smart_approve", "chat"
123124
}
124125

125126
// PIIDetectionConfig configures automatic PII detection on inbound messages.
@@ -269,6 +270,11 @@ func LoadConfig(path string) (*Config, error) {
269270
cfg.ModelList = ConvertProvidersToModelList(cfg)
270271
}
271272

273+
// Merge catalog: add any default catalog entries not already in the user's list.
274+
// This ensures new models added to the built-in catalog in software updates are
275+
// immediately available after restart, without overriding user customizations.
276+
mergeCatalogEntries(cfg)
277+
272278
// Ensure the main/default agent is always present in agents.list.
273279
// This handles existing configs written before the main agent was added to
274280
// DefaultConfig, so existing users get the correct behavior on upgrade.

pkg/config/default_models.go

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,22 @@
11
package config
22

3+
// mergeCatalogEntries appends built-in catalog entries that aren't already
4+
// present in cfg.ModelList (matched by ModelName). User entries always win —
5+
// nothing is removed or overwritten. Called from LoadConfig so that new
6+
// catalog entries added in software updates become available on next restart.
7+
func mergeCatalogEntries(cfg *Config) {
8+
catalog := defaultModelList()
9+
existing := make(map[string]bool, len(cfg.ModelList))
10+
for _, m := range cfg.ModelList {
11+
existing[m.ModelName] = true
12+
}
13+
for _, m := range catalog {
14+
if !existing[m.ModelName] {
15+
cfg.ModelList = append(cfg.ModelList, m)
16+
}
17+
}
18+
}
19+
320
// defaultModelList returns the curated catalog of direct API provider models,
421
// sourced from NousResearch/hermes-agent provider definitions (v0.8.0).
522
// API keys are intentionally empty — users fill them in via config or env vars.

0 commit comments

Comments
 (0)