Summary
When a Model Provider Service is configured for Codex, write_tool_config deliberately leaves model unset so Codex sends its own canonical name. That assumption holds for providers exposing OpenAI-canonical ids, but Azure OpenAI MPS targets are deployment names, which are routinely not canonical (gpt-5.6-luna, my-gpt5-prod, …). The result is that ucode configure --agents codex against an Azure OpenAI MPS configures Codex onto a model the service has no target for.
This is independent of #323 — it still bites after that 400 is fixed.
Where
ucode/agents/codex.py, write_tool_config:
# With a Model Provider Service the gateway routes by header and Codex sends
# its own canonical model name (e.g. `gpt-5`) — leave `model` unset so no
# Databricks endpoint id is pinned. ...
chosen_model = None if provider else (model or default_model(state))
The comment states the assumption plainly; it just isn't true for EXTERNAL_MODEL_PROVIDER_TYPE_AZURE_OPENAI, where config.targets[].model is whatever the Azure deployment is called.
Impact
A developer runs ucode configure --agents codex, gets a "configured" success, and the first request fails because the model name Codex picked isn't a target on the service. Nothing in the configure output hints that the model is the problem.
Workaround
Author a managed config with an explicit default_model — the launch path pins that, so it overrides Codex's own choice:
{"agent": "CODING_AGENT_CODEX",
"model_config": {"codex": {"model_provider_service": "<catalog>.<schema>.<service>",
"default_model": "<azure-deployment-name>"}}}
Suggested fix
The service's targets are already discoverable via GET /api/2.1/unity-catalog/model-provider-services/<full_name> → config.targets[].model. Options, roughly in order of preference:
- When a provider is set, read its targets and pin
model when the target list doesn't contain the name Codex would otherwise send (or when there is exactly one target).
- Failing that, validate at configure time and fail loudly — "service
<name> has no target matching <model>; targets are: …" — rather than writing a config that cannot work.
- At minimum, document that
default_model is effectively required for Azure OpenAI MPS.
Summary
When a Model Provider Service is configured for Codex,
write_tool_configdeliberately leavesmodelunset so Codex sends its own canonical name. That assumption holds for providers exposing OpenAI-canonical ids, but Azure OpenAI MPS targets are deployment names, which are routinely not canonical (gpt-5.6-luna,my-gpt5-prod, …). The result is thatucode configure --agents codexagainst an Azure OpenAI MPS configures Codex onto a model the service has no target for.This is independent of #323 — it still bites after that 400 is fixed.
Where
ucode/agents/codex.py,write_tool_config:The comment states the assumption plainly; it just isn't true for
EXTERNAL_MODEL_PROVIDER_TYPE_AZURE_OPENAI, whereconfig.targets[].modelis whatever the Azure deployment is called.Impact
A developer runs
ucode configure --agents codex, gets a "configured" success, and the first request fails because the model name Codex picked isn't a target on the service. Nothing in the configure output hints that the model is the problem.Workaround
Author a managed config with an explicit
default_model— the launch path pins that, so it overrides Codex's own choice:{"agent": "CODING_AGENT_CODEX", "model_config": {"codex": {"model_provider_service": "<catalog>.<schema>.<service>", "default_model": "<azure-deployment-name>"}}}Suggested fix
The service's targets are already discoverable via
GET /api/2.1/unity-catalog/model-provider-services/<full_name>→config.targets[].model. Options, roughly in order of preference:modelwhen the target list doesn't contain the name Codex would otherwise send (or when there is exactly one target).<name>has no target matching<model>; targets are: …" — rather than writing a config that cannot work.default_modelis effectively required for Azure OpenAI MPS.