fix(moa): forward slot api_mode + pin chat_completions on live MoA switch - #55579
Merged
Conversation
Slot_runtime resolved the provider's real API surface (including api_mode) but only forwarded base_url and api_key to call_llm, dropping api_mode. This caused Copilot GPT-5.x reference slots to hit /chat/completions instead of the Responses API, returning 400 unsupported_api_for_model. - _slot_runtime: forward api_mode from resolve_runtime_provider - call_llm: accept explicit api_mode param, override task config - 4 regression tests for propagation, omission, and signature
The gateway/CLI /model switch path (switch_model in agent_runtime_helpers) built the MoAClient facade but left agent.api_mode at the value determine_api_mode / the resolved aggregator transport produced (e.g. codex_responses or anthropic_messages). The conversation loop dispatches on agent.api_mode, so a non-chat_completions value made the primary/acting call go through client.responses.create — which the MoAClient facade has no .responses for — and fall through to the moa://local placeholder, 404 three times, then fall back to a reference model (issues #54259, #54669). agent_init.py already pins api_mode=chat_completions for provider==moa; mirror that in the live switch so the primary call always routes through MoAClient.chat.completions. The aggregator's real transport is resolved and applied inside the reference/aggregator fan-out, not on the outer call.
This was referenced Jun 30, 2026
Closed
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.
Summary
Two Mixture-of-Agents transport bugs that broke reference and primary calls are now fixed: MoA slots route through their resolved
api_mode, and a live switch to a MoA preset always speakschat_completionson the primary call.Changes
agent/moa_loop.py+agent/auxiliary_client.py:_slot_runtimenow forwards the resolvedapi_mode, andcall_llmaccepts anapi_modeoverride (cherry-picked from @liuhao1024's fix(moa): propagate api_mode from slot runtime to call_llm (#54379) #54384). Fixes Copilot GPT-5.x references 400'ing on/chat/completionsandanthropic_messagesaggregators on unrecognized hosts 404'ing.agent/agent_runtime_helpers.py:switch_modelnow pinsapi_mode = "chat_completions"in theprovider == "moa"branch, mirroringagent_init.py. The aggregator's real transport is resolved inside the reference/aggregator fan-out, never on the outer primary call.test_moa_slot_api_mode.py; addedtest_moa_switch_api_mode.pyasserting the pin holds acrosscodex_responses/anthropic_messages/chat_completions/empty incoming modes.Root cause
_slot_runtimeresolved each slot'sapi_modebut forwarded onlybase_url+api_key. The URL heuristic can't recover the transport for Copilot Responses models or anthropic-wire hosts offapi.anthropic.com, so those slots used the wrong endpoint./modelswitch built theMoAClientfacade but leftagent.api_modeat the aggregator's transport. The conversation loop dispatchedclient.responses.create(MoAClient has no.responses), fell through to themoa://localplaceholder → 404 → fallback to a reference model. The/moaone-shot path already pinnedchat_completions, which is why one-shot worked but persisted presets didn't.Validation
unsupported_api_for_modelcodex_responsesanthropic_messagesmoa://local404 → fallbackMoAClient.chat.completionstest_moa_slot_api_mode/test_moa_switch_api_mode/test_moa_loop_modeCloses #54379, #55268, #54259, #54669.
Infographic
Nous Research