1313 effective_agent_models ,
1414 managed_default_model ,
1515 managed_provider_service ,
16+ managed_supplies_models ,
1617 resolve_state ,
1718)
1819from ucode .state import MANAGED_OVERLAY_KEY
@@ -58,6 +59,7 @@ def _state(**overrides) -> dict:
5859class TestClaudeModels :
5960 def test_proto_slots_map_to_families (self ):
6061 # The manifest keeps proto spelling (`default_opus_model`); render_overlay reads `opus`.
62+ # `fable` has no slot here, so it stays unset rather than inheriting `default_model`.
6163 models = effective_agent_models (MANAGED , _state (), "claude" )
6264 assert models == {
6365 "opus" : "system.ai.claude-opus-5" ,
@@ -70,16 +72,33 @@ def test_manifest_wins_over_local_per_family(self):
7072 models = effective_agent_models (MANAGED , state , "claude" )
7173 assert models ["opus" ] == "system.ai.claude-opus-5"
7274
73- def test_family_absent_from_manifest_keeps_local_value (self ):
74- # Claude resolves per family, so a family the admin didn't pin keeps the developer's choice.
75+ def test_family_absent_from_manifest_is_dropped (self ):
76+ # The manifest is the whole allowlist: a family the admin didn't pin is left unset rather
77+ # than inheriting the developer's model, so a launch can't reach models the admin didn't
78+ # sanction. Nothing is written for it, so the agent uses its own default.
7579 managed = {
7680 "enabled_agents" : {
7781 "claude" : {"model_config" : {"models" : {"default_opus_model" : "managed-opus" }}}
7882 }
7983 }
8084 state = _state (claude_models = {"opus" : "local-opus" , "fable" : "local-fable" })
81- models = effective_agent_models (managed , state , "claude" )
82- assert models == {"opus" : "managed-opus" , "fable" : "local-fable" }
85+ assert effective_agent_models (managed , state , "claude" ) == {"opus" : "managed-opus" }
86+
87+ def test_unset_families_do_not_inherit_the_default_model (self ):
88+ # An admin who names only opus is steering people off the other families, so filling them in
89+ # from `default_model` would quietly re-enable what they left out.
90+ managed = {
91+ "enabled_agents" : {
92+ "claude" : {
93+ "model_config" : {
94+ "default_model" : "managed-default" ,
95+ "models" : {"default_opus_model" : "managed-opus" },
96+ }
97+ }
98+ }
99+ }
100+ state = _state (claude_models = {"sonnet" : "local-sonnet" })
101+ assert effective_agent_models (managed , state , "claude" ) == {"opus" : "managed-opus" }
83102
84103 def test_no_manifest_models_falls_back_to_local (self ):
85104 state = _state (claude_models = {"sonnet" : "local-sonnet" })
@@ -307,3 +326,54 @@ def test_survives_a_config_with_no_model_list(self):
307326 # Nothing lands in the model list, so the launch path must pass the default model into
308327 # resolve_launch_model rather than relying on state having one.
309328 assert resolve_state (managed , state , "codex" ).get ("codex_models" ) is None
329+
330+
331+ class TestManagedSuppliesModels :
332+ """Whether the config already says which models an agent uses, so discovery can be skipped."""
333+
334+ def test_true_when_a_family_slot_is_pinned (self ):
335+ managed = {
336+ "enabled_agents" : {
337+ "claude" : {
338+ "model_config" : {"models" : {"default_opus_model" : "system.ai.claude-opus-5" }}
339+ }
340+ }
341+ }
342+ assert managed_supplies_models (managed , "claude" ) is True
343+
344+ def test_true_for_a_default_model (self ):
345+ managed = {"enabled_agents" : {"codex" : {"model_config" : {"default_model" : "gpt" }}}}
346+ assert managed_supplies_models (managed , "codex" ) is True
347+
348+ def test_true_for_a_provider (self ):
349+ # A provider routes by header and pins no Databricks model, so discovery is moot.
350+ managed = {
351+ "enabled_agents" : {
352+ "claude" : {"model_config" : {"model_provider_service" : "main.default.mps" }}
353+ }
354+ }
355+ assert managed_supplies_models (managed , "claude" ) is True
356+
357+ def test_true_for_a_flat_model_list (self ):
358+ managed = {"enabled_agents" : {"opencode" : {"model_config" : {"models" : ["a" , "b" ]}}}}
359+ assert managed_supplies_models (managed , "opencode" ) is True
360+
361+ def test_false_when_the_config_names_no_models (self ):
362+ # Discovery still has to run, or the launch has nothing to pin.
363+ managed = {"enabled_agents" : {"claude" : {"use_as_global_settings" : True }}}
364+ assert managed_supplies_models (managed , "claude" ) is False
365+
366+ def test_false_for_an_agent_the_config_does_not_cover (self ):
367+ assert managed_supplies_models (MANAGED , "gemini" ) is False
368+
369+ def test_false_for_no_config_at_all (self ):
370+ # First launch has no persisted copy yet, so discovery runs exactly as it always did.
371+ assert managed_supplies_models (None , "claude" ) is False
372+
373+ def test_false_when_slots_are_present_but_blank (self ):
374+ managed = {
375+ "enabled_agents" : {
376+ "claude" : {"model_config" : {"models" : {"default_opus_model" : " " }}}
377+ }
378+ }
379+ assert managed_supplies_models (managed , "claude" ) is False
0 commit comments