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 ──────────────────────────────────────────────────────────