[AIGTWY-4710] Keep managed models across config transitions AIGTWY-4786 - #709
Merged
Merged
Conversation
david-siqi-liu
marked this pull request as ready for review
September 17, 2026 19:06
david-siqi-liu
force-pushed
the
david/aigtwy-4710-model-lifecycle
branch
12 times, most recently
from
September 17, 2026 23:36
181ae42 to
d5eb211
Compare
lilly-luo
reviewed
Sep 18, 2026
lilly-luo
reviewed
Sep 18, 2026
lilly-luo
reviewed
Sep 18, 2026
lilly-luo
reviewed
Sep 18, 2026
Collaborator
|
picker + available model switching is working well for cc. however it doesn't look like the cc family defaults are getting propagated. see https://eng-ml-agent-platform.staging.cloud.databricks.com/ . is this a known limitation ?
i see this in my managed settings but it doesn't match what's in the config, except for the default. moreover, i didn't define FABLE in the managed config |
david-siqi-liu
force-pushed
the
david/aigtwy-4710-model-lifecycle
branch
2 times, most recently
from
September 18, 2026 02:49
26caa1e to
adc7d84
Compare
… workspace Keeps each agent's managed model settings in sync with the managed config: switching between managed configs reconciles to the current one, and configuring a workspace with no managed config clears ug's managed model settings so an unmanaged workspace never enforces a stale list carried over from a previous managed workspace. - Claude clears the managed picker (availableModels, enforceAvailableModels, modelPicker) when not writing a static list. It clears the whole picker in its own ucode-settings.json. In the OS managed-settings.json the picker is shared with the administrator, so ucode reverts it to its pre-ucode baseline only when the live picker is unchanged since ucode last wrote it (a three-way merge of baseline, last write, and live, via a ManagedFileSnapshots value). - Fixes a pre-existing bug where a managed config's per-family default models were dropped: managed_resolve._manifest_models read a stale `models` key instead of the normalized `default_models_by_model_family`, so no ANTHROPIC_DEFAULT_<family>_MODEL was written. Corrects the unit fixtures that masked it and adds a regression test through normalize_managed_config. - Reconciles the per-family default env keys three-way like the picker so a workspace switch drops stale defaults: config, then an admin-authored value (differs from ucode's last write, preserved), then discovery; a value ucode itself wrote is re-derived from the new workspace, and a default whose model is not in the enforced availableModels list is dropped (e.g. a discovered fable default when the admin's list omits fable). - Codex clears its catalog and model_catalog_json pointer on an unmanaged configure or a provider switch; a managed static config writes them. - The UCODE_MANAGED_CONFIG_STUB test hook accepts an explicit null to reproduce a workspace with no managed config. - Adds functional lifecycle tests (both agents) and per-agent managed_fixture integration journeys covering no config -> static A -> static B -> MPS -> no config, plus per-family default coverage and coverage-matrix updates. Co-authored-by: Isaac <no-reply@databricks.com>
david-siqi-liu
force-pushed
the
david/aigtwy-4710-model-lifecycle
branch
from
September 18, 2026 03:10
adc7d84 to
42f241a
Compare
lilly-luo
approved these changes
Sep 18, 2026
Collaborator
david-siqi-liu
enabled auto-merge (squash)
September 18, 2026 03:18
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.




Keeps a coding agent's managed model settings in sync with the managed config across workspace transitions (AIGTWY-4710). Switching between managed configs reconciles each agent's model settings to the current config, and configuring a workspace with no managed config clears ug's managed model settings so an unmanaged workspace never enforces a stale list inherited from a previous managed workspace.
Lifecycle exercised, per agent (functional in-process tests plus end-to-end integration journeys):
Databricks-Model-Provider-Serviceheader routes and there is no static list.Changes:
availableModels,enforceAvailableModels,modelPicker) whenever ug is not writing a static list this run (an unmanaged workspace or a provider switch). It always clears the picker in its ownucode-settings.json. In the OSmanaged-settings.jsonthe picker is shared with the administrator, so ug treats it as one unit and reverts it to its pre-ucode baseline only when the live picker is unchanged since ug last wrote it (a three-way merge of baseline, ug's last write, and the live file). That way ug removes only what it introduced and never an administrator's own picker, a picker they added after ug cleared its own, or one they later edited (the enforce flag included).model_catalog_jsonpointer on an unmanaged configure or a provider switch, so an unmanaged workspace uses its own discovery. A managed static config writes them; the launch-timemodelpin follows Codex's existing clear-when-unmanaged behavior./modelpicker labels: the enforced allow-list still shows one row per model (it can include multiple versions per family and non-Claude models), but each label is now title-cased with a dotted version and known acronyms upper-cased (system.ai.claude-haiku-4-5shows asClaude Haiku 4.5,system.ai.glm-5-3asGLM 5.3) instead of the raw id. The routable id still shows on the right of each row.UCODE_MANAGED_CONFIG_STUBtest hook accepts an explicit JSONnullto reproduce a workspace with no managed config, distinct from an unset or unreadable stub (which still falls through to the real HTTP read).managed_resolve._manifest_modelsread a stalemodelskey instead of the normalizeddefault_models_by_model_family, somanaged_claude_family_modelsreturned nothing and noANTHROPIC_DEFAULT_<family>_MODELwas written (only the overall default and the picker survived, on separate paths). Unit fixtures that hand-built the stale shape masked it; the fix corrects them and adds a regression test that builds throughnormalize_managed_configso the shape can't drift again.ANTHROPIC_DEFAULT_<family>_MODELresolves as config, then an administrator-authored value (one that differs from ug's last write, preserved verbatim), then discovery; a value ug itself wrote is re-derived from the new workspace rather than preserved, and any family default whose model is not in the enforcedavailableModelslist is dropped (e.g. a discoveredfabledefault when the admin's list omits fable).[1m]context tag), per-agentmanaged_fixtureintegration journeys running it throughug configureagainst the managed e2e workspace, and coverage-matrix updates. The integration MPS states point at real provider services on that workspace:main.default.ci_e2e_anthropic_mps(Claude) andmain.default.ci_e2e_openai_mps(Codex).What Claude Code writes for models, by managed model source:
model_services): setsavailableModels,enforceAvailableModels, andmodelPickerin~/.claude/ucode-settings.jsonand the OSmanaged-settings.json. The managed default is applied at launch asenv.ANTHROPIC_MODEL.model_provider_service): writes no model list and clears ug's static picker; theDatabricks-Model-Provider-Serviceheader routes and Claude shows its own model names. A Bedrock-backed provider pinsANTHROPIC_DEFAULT_{OPUS,SONNET,HAIKU}_MODELfrom the manifest's family slots; an Anthropic provider pins nothing.unity_catalog_location: not consumed on main (schema only; no fields written).What Codex writes for models, by managed model source:
model_services): writes the catalog file~/.ucode/codex-model-catalog.jsonand pointsucode.config.toml'smodel_catalog_jsonat it. The managed default is pinned asmodelinucode.config.toml.model_provider_service): writes no catalog and clears any static catalog; theDatabricks-Model-Provider-Serviceheader routes and Codex discovers models at launch.unity_catalog_location: not consumed on main (schema only; no fields written).Known limitations (out of scope here):
managed_writes_allowed()False), ug cannot rewrite the root-owned OSmanaged-settings.json, so a stale picker there is not cleared in that path; the privateucode-settings.jsonstill is. The interactive flow clears both.This pull request and its description were written by Isaac.