fix(auxiliary): keep auto model resolved from runtime pair - #61
Conversation
When provider=auto and the caller omits an explicit model, resolve_provider_client filled model from _read_main_model() before invoking _resolve_auto(). During a mid-session failover this can cross stale config/default model state (claude-opus-4-8) onto the live fallback provider client (openai-codex), producing the observed Codex 400.\n\nSkip the generic model fallback for provider=auto so _resolve_auto(main_runtime=...) supplies the matched provider/model pair. Explicit caller model overrides still win.\n\nRegression: tests/agent/test_auxiliary_main_first.py::TestResolveProviderClientAutoRuntimeModel::test_auto_provider_does_not_let_stale_config_model_override_runtime_model is RED before this fix (returns stale claude-opus-4-8) and GREEN after (returns gpt-5.5).
🔎 Lint report:
|
| Rule | Count |
|---|---|
PLW1514 |
2 |
First entries
scripts/lcm_qa_battery.py:144: [PLW1514] `pathlib.Path(...).write_text` without explicit `encoding` argument
scripts/lcm_arm_b_node_recovery.py:801: [PLW1514] `pathlib.Path(...).write_text` without explicit `encoding` argument
✅ Fixed issues (2):
| Rule | Count |
|---|---|
PLW1514 |
2 |
First entries
../../../../../tmp/lint-base/scripts/lcm_qa_battery.py:144: [PLW1514] `pathlib.Path(...).write_text` without explicit `encoding` argument
../../../../../tmp/lint-base/scripts/lcm_arm_b_node_recovery.py:801: [PLW1514] `pathlib.Path(...).write_text` without explicit `encoding` argument
Unchanged: 0 pre-existing issues carried over.
ty (type checker)
Total: 11193 on HEAD, 11192 on base (🆕 +1)
🆕 New issues (1):
| Rule | Count |
|---|---|
invalid-argument-type |
1 |
First entries
tests/agent/test_auxiliary_main_first.py:571: [invalid-argument-type] invalid-argument-type: Argument to function `resolve_provider_client` is incorrect: Expected `str`, found `None`
✅ Fixed issues: none
Unchanged: 5838 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
| def test_auto_provider_preserves_explicit_model_override(self): | ||
| """A real caller-supplied model still wins over the auto-resolved model.""" | ||
| codex_client = MagicMock() | ||
|
|
||
| with patch( | ||
| "agent.auxiliary_client._resolve_auto", return_value=(codex_client, "gpt-5.5"), | ||
| ): | ||
| from agent.auxiliary_client import resolve_provider_client | ||
|
|
||
| client, model = resolve_provider_client( | ||
| "auto", | ||
| "gpt-5.4-mini", | ||
| False, | ||
| main_runtime={"provider": "openai-codex", "model": "gpt-5.5"}, | ||
| ) | ||
|
|
||
| assert client is codex_client | ||
| assert model == "gpt-5.4-mini" |
There was a problem hiding this comment.
Second test does not assert
main_runtime forwarding to _resolve_auto
test_auto_provider_preserves_explicit_model_override verifies that a caller-supplied model wins over the auto-resolved one, which is correct. However, it doesn't assert that _resolve_auto was actually called with the right main_runtime. If a future refactor accidentally dropped main_runtime from the inner call, this test would still pass. The first test (test_auto_provider_does_not_let_stale_config_model_override_runtime_model) includes mock_resolve_auto.assert_called_once_with(main_runtime=...) — adding the same assertion here would close the gap.
Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!
Unblocks the fork-wide ruff enforcement gate (PLW1514) by adding explicit UTF-8 encodings to LCM report write_text calls.\n\nThis was already failing on clean fork/main and was inherited by PR #61; keep it as a separate hygiene fix rather than mixing it into the auxiliary resolver bugfix. Co-authored-by: Apollo <apollo@daemonarchy.local>
Summary
provider=autoauxiliary resolution so the auto branch keeps the live runtime provider/model pair.claude-opus-4-8from being crossed onto a fallback Codex client that should usegpt-5.5.resolve_provider_client("auto", model=None, main_runtime=...)path.Root cause
resolve_provider_client()filled a missing model from_read_main_model()before entering theprovider == "auto"branch. During mid-session fallback,_resolve_auto(main_runtime=...)correctly selectedopenai-codex / gpt-5.5, but the prefilled stale modelclaude-opus-4-8won over the auto-resolved model. Codex then rejected the request with:Test plan
tests/agent/test_auxiliary_main_first.py::TestResolveProviderClientAutoRuntimeModel::test_auto_provider_does_not_let_stale_config_model_override_runtime_modelAssertionError: assert 'claude-opus-4-8' == 'gpt-5.5'python -m pytest tests/agent/test_auxiliary_main_first.py::TestResolveProviderClientAutoRuntimeModel::test_auto_provider_does_not_let_stale_config_model_override_runtime_model tests/agent/test_auxiliary_main_first.py::TestResolveProviderClientAutoRuntimeModel::test_auto_provider_preserves_explicit_model_override -q -o addopts=''2 passedpython -m pytest tests/agent/test_auxiliary_main_first.py tests/agent/test_auxiliary_client.py tests/agent/test_context_compressor.py -q -o addopts='' -p no:randomly338 passed, 1 warningcall_llm(task="compression", main_runtime={"provider":"openai-codex","model":"gpt-5.5"})with the network call intercepted after kwargs build.model: gpt-5.5;BUG_PRESENT: False.Local fleet status
bf30244ae.