fix(gateway): scope api_server secrets under multiplex profiles - #61283
fix(gateway): scope api_server secrets under multiplex profiles#61283giggling-ginger wants to merge 2 commits into
Conversation
API-server agent entry did not install a profile secret scope when gateway.multiplex_profiles is on, so get_secret (e.g. OPENROUTER_BASE_URL) failed closed during SSE chat completions. Mirror the cron/messenger scope install on _run_agent and /v1/runs paths. Fixes NousResearch#61276
teknium1
left a comment
There was a problem hiding this comment.
Thanks for tracing the API-server executor boundary. The premise is confirmed on current main: gateway/platforms/api_server.py:4052-4096 runs _create_agent() and run_conversation() in a bare executor, while multiplex mode makes unscoped get_secret() calls fail closed (agent/secret_scope.py:149-157). The PR scopes that path and the independent /v1/runs construction/executor path.
Suggested changes
- Add a
/v1/runsregression covering scope visibility during both agent construction andrun_conversation; the new test currently covers only_run_agent, whereas/v1/runshas separate regions at proposedgateway/platforms/api_server.py:4330and:4379.
Automated hermes-sweeper review.
| ) | ||
| # Credential resolution during agent construction must run under | ||
| # the profile secret scope when multiplexing is on (#61276). | ||
| with _api_server_profile_secret_scope(): |
There was a problem hiding this comment.
Please add a /v1/runs regression that verifies a scoped secret is available during agent construction and during the executor-run conversation. The new test currently covers _run_agent only; this path has an independent construction/executor split.
|
Addressed the review feedback in commit |
Rebuilt from PR #61283 onto the /p/<profile>/ routing world (7aa21e3): _profile_scope(None) now enters the DEFAULT profile's runtime scope when multiplexing is active instead of returning nullcontext(). api_server is a port-binding platform living on the default profile, so plain requests (no /p/ prefix) are the primary path — with fail-closed get_secret they crashed with UnscopedSecretError on the first credential read (#61276). All three wrapped call sites (chat-completions executor, /v1/runs agent construction and _run_sync) inherit the fix through the one seam. Single-profile gateways keep the no-op. Regression tests ported from the original PR to the _profile_scope seam. Fixes #61276
|
Merged via PR #65700 — rebuilt on current main with your authorship preserved in git log (rebase merge, commit credited to you). Your diagnosis of #61276 was correct and your PR was ahead of the codebase: the Note: #60726 (background-task UnscopedSecretError) is the same bug class at a different call site ( |
Rebuilt from PR NousResearch#61283 onto the /p/<profile>/ routing world (7aa21e3): _profile_scope(None) now enters the DEFAULT profile's runtime scope when multiplexing is active instead of returning nullcontext(). api_server is a port-binding platform living on the default profile, so plain requests (no /p/ prefix) are the primary path — with fail-closed get_secret they crashed with UnscopedSecretError on the first credential read (NousResearch#61276). All three wrapped call sites (chat-completions executor, /v1/runs agent construction and _run_sync) inherit the fix through the one seam. Single-profile gateways keep the no-op. Regression tests ported from the original PR to the _profile_scope seam. Fixes NousResearch#61276
Rebuilt from PR NousResearch#61283 onto the /p/<profile>/ routing world (e2d534a): _profile_scope(None) now enters the DEFAULT profile's runtime scope when multiplexing is active instead of returning nullcontext(). api_server is a port-binding platform living on the default profile, so plain requests (no /p/ prefix) are the primary path — with fail-closed get_secret they crashed with UnscopedSecretError on the first credential read (NousResearch#61276). All three wrapped call sites (chat-completions executor, /v1/runs agent construction and _run_sync) inherit the fix through the one seam. Single-profile gateways keep the no-op. Regression tests ported from the original PR to the _profile_scope seam. Fixes NousResearch#61276
Summary
gateway.multiplex_profilesis on, credential reads go throughget_secretand fail closed unless a profile secret scope is installed._profile_runtime_scope; api_server (/v1/chat/completionsSSE and/v1/runs) did not, so agent setup raisedUnscopedSecretErroronOPENROUTER_BASE_URL(and any other scoped credential).Fixes #61276
Test plan
scripts/run_tests.sh tests/gateway/test_api_server_multiplex_secret_scope.pytest_run_agent_binds_api_session_context_for_tool_envstill passesgateway.multiplex_profiles: true+ api_server streaming chat completion with OpenRouter