fix(agent): preserve MoA facade when rebuilding primary client (stream retry, rotation, fallback+restore)
When agent.provider == "moa", the MoAClient facade *is* the client - there is no real OpenAI wire endpoint behind the moa://local placeholder. Client rebuilds (_replace_primary_openai_client: stream-retry pool cleanup, credential rotation, dead-connection cleanup, fallback+restore) go through create_openai_client and produce a native OpenAI client while provider stays "moa". The next primary call then either raises a `_moa_prepared_request` TypeError (#78382) or, when _client_kwargs carry an unrelated relay base_url, leaks the request to a foreign gateway (observed as HTTP 503 "group ... no available channel" from an unrelated new-api relay right after an aggregator empty-stream retry). Fix: in create_openai_client, when provider is "moa", return build_moa_facade(agent, model) instead of a native client. This covers every rebuild entry point. The three already-fixed call sites (restore_primary_runtime, try_recover_primary_transport, switch_model) assign the facade directly and do not go through create_openai_client, so they are unaffected. Closes #78382
This commit is contained in:
@@ -2370,6 +2370,17 @@ def create_openai_client(agent, client_kwargs: dict, *, reason: str, shared: boo
|
||||
# copy locks the contract so future transport/keepalive work can't reintroduce
|
||||
# the same class of bug.
|
||||
client_kwargs = dict(client_kwargs)
|
||||
# The MoA virtual provider has no real OpenAI wire endpoint - the facade
|
||||
# *is* the client. Rebuilding a native OpenAI client while
|
||||
# agent.provider == "moa" (client replacement, stream-retry pool cleanup,
|
||||
# credential rotation, fallback+restore) drops the facade: the next primary
|
||||
# call either raises a `_moa_prepared_request` TypeError (#78382) or, when
|
||||
# _client_kwargs carry an unrelated relay base_url, leaks the request to a
|
||||
# foreign gateway. Rebuild the facade instead (build_moa_facade also
|
||||
# re-wires the reference relay, see #53802).
|
||||
if (getattr(agent, "provider", "") or "").strip().lower() == "moa":
|
||||
from agent.moa_loop import build_moa_facade
|
||||
return build_moa_facade(agent, getattr(agent, "model", None) or "default")
|
||||
ssl_ca_cert = client_kwargs.pop("ssl_ca_cert", None)
|
||||
ssl_verify_cfg = client_kwargs.pop("ssl_verify", None)
|
||||
httpx_verify = resolve_httpx_verify(ca_bundle=ssl_ca_cert, ssl_verify=ssl_verify_cfg)
|
||||
|
||||
Reference in New Issue
Block a user