From 6bbbc65b45008fd1155efcd7906e6c279b00c7f2 Mon Sep 17 00:00:00 2001 From: teknium1 <127238744+teknium1@users.noreply.github.com> Date: Wed, 23 Sep 2026 03:02:09 -0700 Subject: [PATCH] fix(image_gen): resolve OpenAI and Meta image base URLs through the secret scope Sibling sites of #119986's class: the openai and meta-ai image backends resolved their API key through get_secret but the base URL through os.environ, so on a multiplexed gateway a routed profile's key was sent to the launch profile's endpoint. Both fields now come from the same scope (get_secret_str, like the DeepInfra video backend after #119986). --- plugins/image_gen/meta-ai/__init__.py | 7 ++++--- plugins/image_gen/openai/__init__.py | 4 ++-- .../plugins/image_gen/test_meta_ai_provider.py | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/plugins/image_gen/meta-ai/__init__.py b/plugins/image_gen/meta-ai/__init__.py index 4ea73dd94b..cfc3aea2af 100644 --- a/plugins/image_gen/meta-ai/__init__.py +++ b/plugins/image_gen/meta-ai/__init__.py @@ -6,10 +6,9 @@ Selection: ``model`` kwarg → ``META_IMAGE_MODEL`` → ``image_gen.meta-ai.mode from __future__ import annotations import logging -import os from typing import Any, Dict, List, Optional, Tuple -from agent.secret_scope import get_secret +from agent.secret_scope import get_secret, get_secret_str from agent.image_gen_provider import ( DEFAULT_ASPECT_RATIO, resolve_aspect_ratio, save_b64_image, save_url_image, success_response) from plugins.image_gen._common import ( @@ -32,7 +31,9 @@ def _resolve_api_key() -> Optional[str]: def _resolve_base_url() -> str: - return (os.environ.get(BASE_URL_ENV) or "").strip() or DEFAULT_BASE_URL + # Through the secret scope like the key: under multiplexing os.environ holds the launch profile's + # endpoint, and a routed profile's key must never be sent to another profile's base URL. + return get_secret_str(BASE_URL_ENV).strip() or DEFAULT_BASE_URL # Model ids are sent verbatim to ``/v1/images/generations``. diff --git a/plugins/image_gen/openai/__init__.py b/plugins/image_gen/openai/__init__.py index ca237b3008..f3b90adfeb 100644 --- a/plugins/image_gen/openai/__init__.py +++ b/plugins/image_gen/openai/__init__.py @@ -12,7 +12,7 @@ import logging import os from typing import Any, Dict, List, Optional, Tuple -from agent.secret_scope import get_secret +from agent.secret_scope import get_secret, get_secret_str from agent.image_gen_provider import DEFAULT_ASPECT_RATIO, resolve_aspect_ratio, success_response from plugins.image_gen._common import ( GPT_IMAGE_2_API_MODEL as API_MODEL, GPT_IMAGE_2_DEFAULT as DEFAULT_MODEL, GPT_IMAGE_2_TIERS, @@ -70,7 +70,7 @@ def _resolve_endpoint() -> Tuple[str, str]: named = str(cfg.get("provider") or "").strip() named_base, named_key = _named_endpoint(named) if named else ("", "") base_url = (str(cfg.get("base_url") or "").strip().rstrip("/") or named_base - or os.environ.get("OPENAI_BASE_URL", "").strip()) + or get_secret_str("OPENAI_BASE_URL").strip()) key_env = str(cfg.get("key_env") or "").strip() api_key = (get_secret(key_env) if key_env else None) or named_key or get_secret("OPENAI_API_KEY") or "" return base_url, api_key diff --git a/tests/plugins/image_gen/test_meta_ai_provider.py b/tests/plugins/image_gen/test_meta_ai_provider.py index 4fc87c8863..53c278fa67 100644 --- a/tests/plugins/image_gen/test_meta_ai_provider.py +++ b/tests/plugins/image_gen/test_meta_ai_provider.py @@ -109,6 +109,24 @@ class TestResolution: monkeypatch.setenv("META_BASE_URL", "https://proxy.internal/v1") assert meta_plugin._resolve_base_url() == "https://proxy.internal/v1" + def test_base_url_follows_the_profile_secret_scope(self, monkeypatch): + """Under multiplexing os.environ is the launch profile's: a routed profile's key must go to + ITS base URL, and a profile without an override gets the default — never the launch URL.""" + from agent.secret_scope import reset_secret_scope, set_multiplex_active, set_secret_scope + + monkeypatch.setenv("META_BASE_URL", "https://launch.example/v1") + set_multiplex_active(True) + try: + for scope, expected in (({"META_BASE_URL": "https://profile-b.example/v1"}, "https://profile-b.example/v1"), + ({}, "https://api.meta.ai/v1")): + token = set_secret_scope(scope) + try: + assert meta_plugin._resolve_base_url() == expected + finally: + reset_secret_scope(token) + finally: + set_multiplex_active(False) + # ── Model resolution ──────────────────────────────────────────────────────────