Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 2 additions & 21 deletions src/iac_code/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,11 +141,6 @@ def _build_canonical_names() -> tuple[str, ...]:
("doubao-", "volcengine_cn"),
)

# Module-level flag — warn once per process when IAC_CODE_BASE_URL is set
# but the active provider is not OpenAICompatible. Reset by tests.
_warned_base_url_ignored: bool = False


# ---------------------------------------------------------------------------
# Environment variable overrides
# ---------------------------------------------------------------------------
Expand Down Expand Up @@ -328,12 +323,8 @@ def get_provider_config(key_name: str) -> dict[str, Any]:
"""Return the persisted per-provider config dict (empty when unset).

When ``key_name`` is the active provider, IAC_CODE_MODEL and
IAC_CODE_BASE_URL env values are overlaid. IAC_CODE_BASE_URL only
applies when the active provider is ``openai_compatible``; setting
it for other providers logs a one-time warning and is ignored.
IAC_CODE_BASE_URL env values are overlaid.
"""
global _warned_base_url_ignored

key_name = _LEGACY_KEY_NAME_ALIASES.get(key_name, key_name)
settings = _load_yaml(get_settings_path())
providers = settings.get("providers")
Expand Down Expand Up @@ -361,17 +352,7 @@ def get_provider_config(key_name: str) -> dict[str, Any]:
if env["model"]:
entry["model"] = env["model"]
if env["api_base"]:
if active_key == "openai_compatible":
entry["apiBase"] = env["api_base"]
elif not _warned_base_url_ignored:
from loguru import logger

logger.warning(
"IAC_CODE_BASE_URL is set but active provider is "
f"{active_key!r}; the value is ignored. "
"IAC_CODE_BASE_URL only applies to OpenAICompatible."
)
_warned_base_url_ignored = True
entry["apiBase"] = env["api_base"]

return entry

Expand Down
8 changes: 3 additions & 5 deletions src/iac_code/providers/manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -414,11 +414,9 @@ def create_provider(
provider_cfg = get_provider_config(provider_key)
else:
provider_cfg = copy.deepcopy(provider_config_override)
effective_base_url = base_url or desc.base_url
if not effective_base_url:
saved_base = provider_cfg.get("apiBase")
if isinstance(saved_base, str) and saved_base:
effective_base_url = saved_base
saved_base = provider_cfg.get("apiBase")
configured_base_url = saved_base if isinstance(saved_base, str) and saved_base else None
effective_base_url = base_url or configured_base_url or desc.base_url
effort_value = _get_provider_config_value(provider_cfg, model, "effort")
effort = effort_value if isinstance(effort_value, str) else None
if request_policy_override is not None and request_policy_override.effort is not None:
Expand Down
31 changes: 31 additions & 0 deletions tests/providers/test_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,37 @@ async def _collect_stream_events(stream):


class TestCreateProvider:
@pytest.mark.parametrize("provider_key", PROVIDER_REGISTRY)
def test_saved_api_base_overrides_registry_default_for_every_provider(self, provider_key):
descriptor = PROVIDER_REGISTRY[provider_key]
model = descriptor.default_model or "custom-model"
custom_base_url = "https://saved.example/v1"

provider = create_provider(
model,
credentials={provider_key: "fake-key"},
provider_key_override=provider_key,
provider_config_override={"apiBase": custom_base_url},
)

assert str(provider._client.base_url).rstrip("/") == custom_base_url

@pytest.mark.parametrize("provider_key", PROVIDER_REGISTRY)
def test_explicit_base_url_overrides_saved_and_registry_urls_for_every_provider(self, provider_key):
descriptor = PROVIDER_REGISTRY[provider_key]
model = descriptor.default_model or "custom-model"
explicit_base_url = "https://explicit.example/v1"

provider = create_provider(
model,
credentials={provider_key: "fake-key"},
provider_key_override=provider_key,
base_url=explicit_base_url,
provider_config_override={"apiBase": "https://saved.example/v1"},
)

assert str(provider._client.base_url).rstrip("/") == explicit_base_url

def test_anthropic(self, monkeypatch):
monkeypatch.setattr("iac_code.config.get_active_provider_key", lambda: "anthropic")
p = create_provider("claude-sonnet-4-6", credentials={"anthropic": "key"})
Expand Down
32 changes: 14 additions & 18 deletions tests/test_config_env_overrides.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,7 @@

import pytest


@pytest.fixture(autouse=True)
def _reset_warn_state():
"""Reset module-level warn flag between tests so warning behavior is deterministic."""
import iac_code.config as cfg

cfg._warned_base_url_ignored = False
yield
cfg._warned_base_url_ignored = False
from iac_code.providers.registry import PROVIDER_REGISTRY


class TestGetEnvOverrides:
Expand Down Expand Up @@ -224,18 +216,19 @@ def test_model_env_does_not_leak_to_other_providers(self, monkeypatch, tmp_path)

assert get_provider_config("bailian")["model"] == "qwen3.6-plus"

def test_base_url_env_overlays_when_active_is_openai_compatible(self, monkeypatch, tmp_path):
@pytest.mark.parametrize("provider_key", PROVIDER_REGISTRY)
def test_base_url_env_overlays_active_provider(self, monkeypatch, tmp_path, provider_key):
from unittest.mock import patch

self._write_settings(
tmp_path,
("activeProvider: openai_compatible\nproviders:\n openai_compatible:\n apiBase: https://old/v1\n"),
f"activeProvider: {provider_key}\nproviders:\n {provider_key}:\n apiBase: https://old/v1\n",
)
monkeypatch.setenv("IAC_CODE_BASE_URL", "https://new/v1")
with patch("iac_code.config.Path.home", return_value=tmp_path):
from iac_code.config import get_provider_config

assert get_provider_config("openai_compatible")["apiBase"] == "https://new/v1"
assert get_provider_config(provider_key)["apiBase"] == "https://new/v1"

def test_openapi_compatible_settings_key_is_legacy_alias_for_openai_compatible(self, monkeypatch, tmp_path):
from unittest.mock import patch
Expand All @@ -252,21 +245,24 @@ def test_openapi_compatible_settings_key_is_legacy_alias_for_openai_compatible(s
assert get_provider_config("openai_compatible")["apiBase"] == "https://new/v1"
assert get_provider_config("openapi_compatible")["apiBase"] == "https://new/v1"

def test_base_url_env_ignored_when_active_is_not_openai_compatible(self, monkeypatch, tmp_path, caplog):
import logging
def test_base_url_env_does_not_leak_to_inactive_provider(self, monkeypatch, tmp_path):
from unittest.mock import patch

self._write_settings(
tmp_path,
"activeProvider: openai\nproviders:\n openai:\n model: gpt-5.4\n",
(
"activeProvider: openai\n"
"providers:\n"
" openai:\n model: gpt-5.4\n"
" dashscope:\n apiBase: https://saved.example/v1\n"
),
)
monkeypatch.setenv("IAC_CODE_BASE_URL", "https://example/v1")
with patch("iac_code.config.Path.home", return_value=tmp_path):
from iac_code.config import get_provider_config

with caplog.at_level(logging.WARNING):
cfg = get_provider_config("openai")
assert "apiBase" not in cfg or cfg.get("apiBase") != "https://example/v1"
cfg = get_provider_config("dashscope")
assert cfg["apiBase"] == "https://saved.example/v1"

def test_env_overlay_does_not_mutate_unset_fields(self, monkeypatch, tmp_path):
from unittest.mock import patch
Expand Down
4 changes: 3 additions & 1 deletion website/docs/configuration/environment-variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,13 @@ Environment variables are useful for CI/CD pipelines, containers, and one-off ov
|---|---|
| `IAC_CODE_PROVIDER` | Model provider name (case-insensitive). Valid values: `DashScope`, `DashScope Token Plan`, `OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `Azure OpenAI`, `ModelScope`, `Kimi CN`, `Kimi Intl`, `MiniMax CN`, `MiniMax Intl`, `ZhiPu CN`, `ZhiPu Intl`, `Volcengine CN`, `SiliconFlow CN`, `SiliconFlow Intl`, `Aliyun CodingPlan`, `Aliyun CodingPlan Intl`, `ZhiPu CN CodingPlan`, `ZhiPu Intl CodingPlan`, `Volcengine CodingPlan`, `OpenAI Compatible`, `Anthropic Compatible`, `OpenRouter`, `Ollama`, `LM Studio` |
| `IAC_CODE_MODEL` | Model name |
| `IAC_CODE_BASE_URL` | API endpoint for `OpenAI Compatible` only; ignored (with a warning) for other providers |
| `IAC_CODE_BASE_URL` | API endpoint override for the active provider; takes precedence over the saved `apiBase` and built-in default URL |
| `IAC_CODE_API_KEY` | Provider API key; overrides the active provider's key in `.credentials.yml` |

See [LLM Providers](./llm-providers.md) for provider details.

The effective provider Base URL precedence is: explicit runtime override, `IAC_CODE_BASE_URL`, saved `apiBase`, provider registry default, then SDK default.

## Alibaba Cloud Credentials

| Variable | Description |
Expand Down
2 changes: 1 addition & 1 deletion website/docs/configuration/llm-providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI arguments > environment variables > configuration files
|---|---|
| `IAC_CODE_PROVIDER` | Model provider name (case-insensitive). See tables above for valid values |
| `IAC_CODE_MODEL` | Model name |
| `IAC_CODE_BASE_URL` | API endpoint for `OpenAI Compatible` only; ignored (with a warning) for other providers |
| `IAC_CODE_BASE_URL` | API endpoint override for the active provider; takes precedence over the saved `apiBase` and built-in default URL |
| `IAC_CODE_API_KEY` | Provider API key |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Umgebungsvariablen sind nuetzlich fuer CI/CD-Pipelines, Container und einmalige
|---|---|
| `IAC_CODE_PROVIDER` | Name des Modellanbieters (Gross-/Kleinschreibung wird nicht beachtet). Gueltige Werte: `DashScope`, `DashScope Token Plan`, `OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `Azure OpenAI`, `ModelScope`, `Kimi CN`, `Kimi Intl`, `MiniMax CN`, `MiniMax Intl`, `ZhiPu CN`, `ZhiPu Intl`, `Volcengine CN`, `SiliconFlow CN`, `SiliconFlow Intl`, `Aliyun CodingPlan`, `Aliyun CodingPlan Intl`, `ZhiPu CN CodingPlan`, `ZhiPu Intl CodingPlan`, `Volcengine CodingPlan`, `OpenAPI Compatible`, `Anthropic Compatible`, `OpenRouter`, `Ollama`, `LM Studio` |
| `IAC_CODE_MODEL` | Modellname |
| `IAC_CODE_BASE_URL` | API-Endpunkt nur fuer `OpenAI Compatible`; wird fuer andere Anbieter ignoriert (mit einer Warnung) |
| `IAC_CODE_BASE_URL` | Überschreibt den API-Endpunkt des aktiven Anbieters; hat Vorrang vor dem gespeicherten `apiBase` und der integrierten Standard-URL |
| `IAC_CODE_API_KEY` | API-Schluessel des Anbieters; ueberschreibt den Schluessel des aktiven Anbieters in `.credentials.yml` |

Siehe [LLM-Anbieter](./llm-providers.md) fuer Anbieterdetails.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI-Argumente > Umgebungsvariablen > Konfigurationsdateien
|---|---|
| `IAC_CODE_PROVIDER` | Name des Modellanbieters (Gross-/Kleinschreibung wird nicht beachtet). Gueltige Werte siehe obige Tabellen |
| `IAC_CODE_MODEL` | Modellname |
| `IAC_CODE_BASE_URL` | API-Endpunkt nur fuer `OpenAI Compatible`; wird fuer andere Anbieter ignoriert (mit einer Warnung) |
| `IAC_CODE_BASE_URL` | Überschreibt den API-Endpunkt des aktiven Anbieters; hat Vorrang vor dem gespeicherten `apiBase` und der integrierten Standard-URL |
| `IAC_CODE_API_KEY` | API-Schluessel des Anbieters |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Las variables de entorno son utiles para pipelines de CI/CD, contenedores y sobr
|---|---|
| `IAC_CODE_PROVIDER` | Nombre del proveedor de modelos (sin distincion de mayusculas/minusculas). Valores validos: `DashScope`, `DashScope Token Plan`, `OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `Azure OpenAI`, `ModelScope`, `Kimi CN`, `Kimi Intl`, `MiniMax CN`, `MiniMax Intl`, `ZhiPu CN`, `ZhiPu Intl`, `Volcengine CN`, `SiliconFlow CN`, `SiliconFlow Intl`, `Aliyun CodingPlan`, `Aliyun CodingPlan Intl`, `ZhiPu CN CodingPlan`, `ZhiPu Intl CodingPlan`, `Volcengine CodingPlan`, `OpenAPI Compatible`, `Anthropic Compatible`, `OpenRouter`, `Ollama`, `LM Studio` |
| `IAC_CODE_MODEL` | Nombre del modelo |
| `IAC_CODE_BASE_URL` | Endpoint de API que se aplica únicamente a `OpenAPI Compatible`; se ignora (con una advertencia) para otros proveedores |
| `IAC_CODE_BASE_URL` | Sobrescribe el endpoint de API del proveedor activo; tiene prioridad sobre el `apiBase` guardado y la URL predeterminada integrada |
| `IAC_CODE_API_KEY` | Clave API del proveedor; sobreescribe la clave del proveedor activo en `.credentials.yml` |

Consulta [Proveedores de LLM](./llm-providers.md) para mas detalles sobre los proveedores.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI arguments > environment variables > configuration files
|---|---|
| `IAC_CODE_PROVIDER` | Nombre del proveedor de modelos (sin distincion de mayusculas/minusculas). Consulta las tablas anteriores para valores validos |
| `IAC_CODE_MODEL` | Nombre del modelo |
| `IAC_CODE_BASE_URL` | Endpoint de API que se aplica únicamente a `OpenAPI Compatible`; se ignora (con una advertencia) para otros proveedores |
| `IAC_CODE_BASE_URL` | Sobrescribe el endpoint de API del proveedor activo; tiene prioridad sobre el `apiBase` guardado y la URL predeterminada integrada |
| `IAC_CODE_API_KEY` | Clave API del proveedor |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ Les variables d'environnement sont utiles pour les pipelines CI/CD, les conteneu
|---|---|
| `IAC_CODE_PROVIDER` | Nom du fournisseur de modèles (insensible à la casse). Valeurs valides : `DashScope`, `DashScope Token Plan`, `OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `Azure OpenAI`, `ModelScope`, `Kimi CN`, `Kimi Intl`, `MiniMax CN`, `MiniMax Intl`, `ZhiPu CN`, `ZhiPu Intl`, `Volcengine CN`, `SiliconFlow CN`, `SiliconFlow Intl`, `Aliyun CodingPlan`, `Aliyun CodingPlan Intl`, `ZhiPu CN CodingPlan`, `ZhiPu Intl CodingPlan`, `Volcengine CodingPlan`, `OpenAPI Compatible`, `Anthropic Compatible`, `OpenRouter`, `Ollama`, `LM Studio` |
| `IAC_CODE_MODEL` | Nom du modèle |
| `IAC_CODE_BASE_URL` | Point de terminaison API pour `OpenAPI Compatible` uniquement ; ignoré (avec un avertissement) pour les autres fournisseurs |
| `IAC_CODE_BASE_URL` | Remplace le point de terminaison API du fournisseur actif ; prioritaire sur l’`apiBase` enregistré et l’URL intégrée par défaut |
| `IAC_CODE_API_KEY` | Clé API du fournisseur ; remplace la clé du fournisseur actif dans `.credentials.yml` |

Consultez [Fournisseurs LLM](./llm-providers.md) pour les détails des fournisseurs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI arguments > environment variables > configuration files
|---|---|
| `IAC_CODE_PROVIDER` | Nom du fournisseur de modèles (insensible à la casse). Consultez les tableaux ci-dessus pour les valeurs valides |
| `IAC_CODE_MODEL` | Nom du modèle |
| `IAC_CODE_BASE_URL` | Point de terminaison API pour `OpenAPI Compatible` uniquement ; ignoré (avec un avertissement) pour les autres fournisseurs |
| `IAC_CODE_BASE_URL` | Remplace le point de terminaison API du fournisseur actif ; prioritaire sur l’`apiBase` enregistré et l’URL intégrée par défaut |
| `IAC_CODE_API_KEY` | Clé API du fournisseur |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ CLI 引数 > 環境変数 > 設定ファイル
|---|---|
| `IAC_CODE_PROVIDER` | モデルプロバイダー名(大文字小文字不問)。有効な値:`DashScope`、`DashScope Token Plan`、`OpenAI`、`Anthropic`、`DeepSeek`、`Gemini`、`Azure OpenAI`、`ModelScope`、`Kimi CN`、`Kimi Intl`、`MiniMax CN`、`MiniMax Intl`、`ZhiPu CN`、`ZhiPu Intl`、`Volcengine CN`、`SiliconFlow CN`、`SiliconFlow Intl`、`Aliyun CodingPlan`、`Aliyun CodingPlan Intl`、`ZhiPu CN CodingPlan`、`ZhiPu Intl CodingPlan`、`Volcengine CodingPlan`、`OpenAPI Compatible`、`Anthropic Compatible`、`OpenRouter`、`Ollama`、`LM Studio` |
| `IAC_CODE_MODEL` | モデル名 |
| `IAC_CODE_BASE_URL` | `OpenAI Compatible` 専用の API エンドポイント。他のプロバイダーでは無視され、warning が表示されます |
| `IAC_CODE_BASE_URL` | 現在アクティブなプロバイダーの API エンドポイントを上書きします。保存済みの `apiBase` と組み込みの既定 URL より優先されます |
| `IAC_CODE_API_KEY` | プロバイダー API キー。`.credentials.yml` のアクティブプロバイダーのキーを上書きします |

詳細は [LLM プロバイダー](./llm-providers.md) をご覧ください。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI 引数 > 環境変数 > 設定ファイル
|---|---|
| `IAC_CODE_PROVIDER` | モデルプロバイダー名(大文字小文字不問)。有効な値は上記の表を参照 |
| `IAC_CODE_MODEL` | モデル名 |
| `IAC_CODE_BASE_URL` | `OpenAI Compatible` 専用の API エンドポイント。他のプロバイダーでは無視され、warning が表示されます |
| `IAC_CODE_BASE_URL` | 現在アクティブなプロバイダーの API エンドポイントを上書きします。保存済みの `apiBase` と組み込みの既定 URL より優先されます |
| `IAC_CODE_API_KEY` | プロバイダー API キー |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ As variaveis de ambiente sao uteis para pipelines de CI/CD, containers e substit
|---|---|
| `IAC_CODE_PROVIDER` | Nome do provedor de modelo (insensivel a maiusculas e minusculas). Valores validos: `DashScope`, `DashScope Token Plan`, `OpenAI`, `Anthropic`, `DeepSeek`, `Gemini`, `Azure OpenAI`, `ModelScope`, `Kimi CN`, `Kimi Intl`, `MiniMax CN`, `MiniMax Intl`, `ZhiPu CN`, `ZhiPu Intl`, `Volcengine CN`, `SiliconFlow CN`, `SiliconFlow Intl`, `Aliyun CodingPlan`, `Aliyun CodingPlan Intl`, `ZhiPu CN CodingPlan`, `ZhiPu Intl CodingPlan`, `Volcengine CodingPlan`, `OpenAPI Compatible`, `Anthropic Compatible`, `OpenRouter`, `Ollama`, `LM Studio` |
| `IAC_CODE_MODEL` | Nome do modelo |
| `IAC_CODE_BASE_URL` | Endpoint de API aplicável apenas a `OpenAPI Compatible`; ignorado (com um aviso) para outros provedores |
| `IAC_CODE_BASE_URL` | Substitui o endpoint de API do provedor ativo; tem precedência sobre o `apiBase` salvo e a URL padrão integrada |
| `IAC_CODE_API_KEY` | Chave de API do provedor; substitui a chave do provedor ativo em `.credentials.yml` |

Consulte [Provedores de LLM](./llm-providers.md) para detalhes sobre os provedores.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI arguments > environment variables > configuration files
|---|---|
| `IAC_CODE_PROVIDER` | Nome do provedor de modelo (insensivel a maiusculas e minusculas). Consulte as tabelas acima para valores validos |
| `IAC_CODE_MODEL` | Nome do modelo |
| `IAC_CODE_BASE_URL` | Endpoint de API aplicável apenas a `OpenAPI Compatible`; ignorado (com um aviso) para outros provedores |
| `IAC_CODE_BASE_URL` | Substitui o endpoint de API do provedor ativo; tem precedência sobre o `apiBase` salvo e a URL padrão integrada |
| `IAC_CODE_API_KEY` | Chave de API do provedor |
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ CLI 参数 > 环境变量 > 配置文件
|---|---|
| `IAC_CODE_PROVIDER` | 模型提供商名称(大小写不敏感)。有效值:`DashScope`、`DashScope Token Plan`、`OpenAI`、`Anthropic`、`DeepSeek`、`Gemini`、`Azure OpenAI`、`ModelScope`、`Kimi CN`、`Kimi Intl`、`MiniMax CN`、`MiniMax Intl`、`ZhiPu CN`、`ZhiPu Intl`、`Volcengine CN`、`SiliconFlow CN`、`SiliconFlow Intl`、`Aliyun CodingPlan`、`Aliyun CodingPlan Intl`、`ZhiPu CN CodingPlan`、`ZhiPu Intl CodingPlan`、`Volcengine CodingPlan`、`OpenAPI Compatible`、`Anthropic Compatible`、`OpenRouter`、`Ollama`、`LM Studio` |
| `IAC_CODE_MODEL` | 模型名称 |
| `IAC_CODE_BASE_URL` | 仅 `OpenAI Compatible` 使用的 API 端点;其他提供商会忽略此值(并给出 warning) |
| `IAC_CODE_BASE_URL` | 当前激活 Provider 的 API 端点覆盖;优先于配置文件中的 `apiBase` 和内置默认 URL |
| `IAC_CODE_API_KEY` | 提供商 API Key;覆盖 `.credentials.yml` 中活跃提供商的密钥 |

详见 [LLM 提供商](./llm-providers.md)。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,5 +74,5 @@ CLI 参数 > 环境变量 > 配置文件
|---|---|
| `IAC_CODE_PROVIDER` | 模型提供商名称(大小写不敏感),有效值见上表 |
| `IAC_CODE_MODEL` | 模型名称 |
| `IAC_CODE_BASE_URL` | 仅 `OpenAI Compatible` 使用的 API 端点;其他提供商会忽略此值(并给出 warning) |
| `IAC_CODE_BASE_URL` | 当前激活 Provider 的 API 端点覆盖;优先于配置文件中的 `apiBase` 和内置默认 URL |
| `IAC_CODE_API_KEY` | 提供商 API Key |
Loading