Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions pkg/config/runtime.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package config

import (
"log/slog"
"maps"
"slices"
"sync"

Expand All @@ -23,6 +24,7 @@ type Config struct {
DefaultModel *latest.ModelConfig
GlobalCodeMode bool
WorkingDir string
Models map[string]latest.ModelConfig

// Hook overrides from CLI flags
HookPreToolUse []string
Expand All @@ -37,6 +39,7 @@ func (runConfig *RuntimeConfig) Clone() *RuntimeConfig {
Config: runConfig.Config,
}
clone.EnvFiles = slices.Clone(runConfig.EnvFiles)
clone.Models = maps.Clone(runConfig.Models)
clone.DefaultModel = runConfig.DefaultModel.Clone()
clone.HookPreToolUse = slices.Clone(runConfig.HookPreToolUse)
clone.HookPostToolUse = slices.Clone(runConfig.HookPostToolUse)
Expand Down
53 changes: 53 additions & 0 deletions pkg/config/runtime_clone_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,56 @@ func TestClone_EnvFilesIsolated(t *testing.T) {
assert.Len(t, original.EnvFiles, 2, "original must not be modified when clone is mutated")
assert.Len(t, clone.EnvFiles, 3)
}

func TestClone_ModelsIsolated(t *testing.T) {
temp := 0.7
original := &RuntimeConfig{
Config: Config{
Models: map[string]latest.ModelConfig{
"model1": {
Provider: "openai",
Model: "gpt-4o",
Temperature: &temp,
},
},
},
}

clone := original.Clone()

// Mutate the clone's Models map
clone.Models["model2"] = latest.ModelConfig{
Provider: "anthropic",
Model: "claude-3",
}

// Mutate an existing model in the clone
newTemp := 0.9
clone.Models["model1"] = latest.ModelConfig{
Provider: "openai",
Model: "gpt-4o-mini",
Temperature: &newTemp,
}

// Original must not be affected by mutations to the clone
assert.Len(t, original.Models, 1, "original must not have new models added")
assert.Equal(t, "gpt-4o", original.Models["model1"].Model)
assert.InDelta(t, 0.7, *original.Models["model1"].Temperature, 0.001)

// Clone should have the mutations
assert.Len(t, clone.Models, 2)
assert.Equal(t, "gpt-4o-mini", clone.Models["model1"].Model)
assert.Equal(t, "claude-3", clone.Models["model2"].Model)
}

func TestClone_NilModels(t *testing.T) {
original := &RuntimeConfig{
Config: Config{
Models: nil,
},
}

clone := original.Clone()

assert.Nil(t, clone.Models)
}
1 change: 1 addition & 0 deletions pkg/teamloader/registry.go
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ func createRAGTool(ctx context.Context, toolset latest.Toolset, parentDir string
ParentDir: parentDir,
ModelsGateway: runConfig.ModelsGateway,
Env: runConfig.EnvProvider(),
Models: runConfig.Models,
})
if err != nil {
return nil, fmt.Errorf("failed to create RAG manager: %w", err)
Expand Down
3 changes: 3 additions & 0 deletions pkg/teamloader/teamloader.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,9 @@ func LoadWithConfig(ctx context.Context, agentSource config.Source, runConfig *c
return nil, err
}

// Make model definitions available to toolset creators (e.g., RAG reranking)
runConfig.Models = cfg.Models

// Load agents
parentDir := cmp.Or(agentSource.ParentDir(), runConfig.WorkingDir)
configName := configNameFromSource(agentSource.Name())
Expand Down
Loading