TestWithAgentModel covers the LocalRuntime.WithAgentModel helper. The helper is the public entry point for "apply a temporary model override for a scope, then CAS-restore it"; it composes resolution (SetAgentModel) with the agent-level snapshot/restore primitives.
(t *testing.T)
| 15 | // for a scope, then CAS-restore it"; it composes resolution (SetAgentModel) |
| 16 | // with the agent-level snapshot/restore primitives. |
| 17 | func TestWithAgentModel(t *testing.T) { |
| 18 | t.Parallel() |
| 19 | |
| 20 | t.Run("agent not found returns no-op restore and error", func(t *testing.T) { |
| 21 | t.Parallel() |
| 22 | tm := team.New(team.WithAgents(agent.New("root", "test"))) |
| 23 | r := &LocalRuntime{ |
| 24 | team: tm, |
| 25 | modelSwitcherCfg: &ModelSwitcherConfig{}, |
| 26 | } |
| 27 | |
| 28 | restore, err := r.WithAgentModel(t.Context(), "missing", "openai/gpt-4o") |
| 29 | require.Error(t, err) |
| 30 | assert.Contains(t, err.Error(), "agent not found") |
| 31 | require.NotNil(t, restore, "restore must always be non-nil") |
| 32 | assert.NotPanics(t, restore, "restore on error must be a safe no-op") |
| 33 | }) |
| 34 | |
| 35 | t.Run("nil modelSwitcherCfg returns no-op restore and error", func(t *testing.T) { |
| 36 | t.Parallel() |
| 37 | root := agent.New("root", "test") |
| 38 | tm := team.New(team.WithAgents(root)) |
| 39 | r := &LocalRuntime{team: tm} // modelSwitcherCfg is nil |
| 40 | |
| 41 | restore, err := r.WithAgentModel(t.Context(), "root", "openai/gpt-4o") |
| 42 | require.Error(t, err) |
| 43 | require.NotNil(t, restore) |
| 44 | assert.NotPanics(t, restore) |
| 45 | assert.False(t, root.HasModelOverride(), "agent state must not be touched on error") |
| 46 | }) |
| 47 | |
| 48 | t.Run("invalid model ref returns no-op restore and error", func(t *testing.T) { |
| 49 | t.Parallel() |
| 50 | root := agent.New("root", "test") |
| 51 | tm := team.New(team.WithAgents(root)) |
| 52 | r := &LocalRuntime{ |
| 53 | team: tm, |
| 54 | modelSwitcherCfg: &ModelSwitcherConfig{}, |
| 55 | } |
| 56 | |
| 57 | // "invalid" has no slash → not an inline spec, and no named config |
| 58 | // matches → SetAgentModel returns an error. |
| 59 | restore, err := r.WithAgentModel(t.Context(), "root", "invalid") |
| 60 | require.Error(t, err) |
| 61 | require.NotNil(t, restore) |
| 62 | assert.NotPanics(t, restore) |
| 63 | assert.False(t, root.HasModelOverride(), "agent state must not be touched on error") |
| 64 | }) |
| 65 | |
| 66 | t.Run("apply clears existing override; restore puts it back", func(t *testing.T) { |
| 67 | t.Parallel() |
| 68 | // Pre-existing override (e.g. set by the user via the model picker |
| 69 | // before the skill ran). |
| 70 | userPick := &mockProvider{id: "user/pick"} |
| 71 | root := agent.New("root", "test", agent.WithModel(&mockProvider{id: "default/model"})) |
| 72 | root.SetModelOverride(userPick) |
| 73 | require.Equal(t, "user/pick", root.Model(t.Context()).ID().String()) |
| 74 |
nothing calls this directly
no test coverage detected