diff --git a/lib/crewai/src/crewai/llms/providers/azure/completion.py b/lib/crewai/src/crewai/llms/providers/azure/completion.py index 156fa8984..fc68b42be 100644 --- a/lib/crewai/src/crewai/llms/providers/azure/completion.py +++ b/lib/crewai/src/crewai/llms/providers/azure/completion.py @@ -155,6 +155,22 @@ class AzureCompletion(BaseLLM): return AsyncChatCompletionsClient(**self._make_client_kwargs()) def _make_client_kwargs(self) -> dict[str, Any]: + # Re-read env vars so that a deferred build can pick up credentials + # that weren't set at instantiation time (e.g. LLM constructed at + # module import before deployment env vars were injected). + if not self.api_key: + self.api_key = os.getenv("AZURE_API_KEY") + if not self.endpoint: + endpoint = ( + os.getenv("AZURE_ENDPOINT") + or os.getenv("AZURE_OPENAI_ENDPOINT") + or os.getenv("AZURE_API_BASE") + ) + if endpoint: + self.endpoint = AzureCompletion._validate_and_fix_endpoint( + endpoint, self.model + ) + if not self.api_key: raise ValueError( "Azure API key is required. Set AZURE_API_KEY environment " diff --git a/lib/crewai/tests/llms/azure/test_azure.py b/lib/crewai/tests/llms/azure/test_azure.py index bee767157..d5efcfc69 100644 --- a/lib/crewai/tests/llms/azure/test_azure.py +++ b/lib/crewai/tests/llms/azure/test_azure.py @@ -416,6 +416,32 @@ async def test_azure_aclose_is_noop_when_uninitialized(): pass +def test_azure_lazy_build_reads_env_vars_set_after_construction(): + """When `LLM(model="azure/...")` is constructed before env vars are set, + the lazy client builder must re-read `AZURE_API_KEY` / `AZURE_ENDPOINT` + so the LLM actually works once credentials become available.""" + from crewai.llms.providers.azure.completion import AzureCompletion + + with patch.dict(os.environ, {}, clear=True): + llm = AzureCompletion(model="gpt-4") + assert llm.api_key is None + assert llm.endpoint is None + + with patch.dict( + os.environ, + { + "AZURE_API_KEY": "late-key", + "AZURE_ENDPOINT": "https://test.openai.azure.com/openai/deployments/gpt-4", + }, + clear=True, + ): + client = llm._get_sync_client() + assert client is not None + assert llm.api_key == "late-key" + assert llm.endpoint is not None + assert "test.openai.azure.com" in llm.endpoint + + def test_azure_endpoint_configuration(): """ Test that Azure endpoint configuration works with multiple environment variable names