@@ -146,14 +146,148 @@ def test_litellm_caller_handles_literal_extra_headers(self):
146146 )
147147 }
148148 )
149-
149+
150150 # Create LiteLLMCaller
151151 caller = LiteLLMCaller (llm_config , debug_mode = True )
152-
152+
153153 # Get model kwargs - this should work without errors
154154 model_kwargs = caller ._get_model_kwargs ("test-model" )
155-
155+
156156 # Verify that extra_headers were passed through
157157 assert "extra_headers" in model_kwargs
158158 assert model_kwargs ["extra_headers" ]["HTTP-Referer" ] == "https://literal-app.com"
159159 assert model_kwargs ["extra_headers" ]["X-Title" ] == "LiteralApp"
160+
161+ def test_custom_endpoint_with_env_var_api_key (self , monkeypatch ):
162+ """Custom endpoint should pass api_key in kwargs when using env var."""
163+ monkeypatch .setenv ("CUSTOM_LLM_KEY" , "sk-custom-12345" )
164+
165+ # Create LLM config for custom endpoint with env var in api_key
166+ llm_config = LLMConfig (
167+ models = {
168+ "custom-model" : ModelConfig (
169+ model_name = "custom-model-name" ,
170+ model_url = "https://custom-llm.example.com/v1" ,
171+ api_key = "${CUSTOM_LLM_KEY}"
172+ )
173+ }
174+ )
175+
176+ # Create LiteLLMCaller
177+ caller = LiteLLMCaller (llm_config , debug_mode = True )
178+
179+ # Get model kwargs
180+ model_kwargs = caller ._get_model_kwargs ("custom-model" )
181+
182+ # Verify that api_key is in kwargs (critical for custom endpoints)
183+ assert "api_key" in model_kwargs
184+ assert model_kwargs ["api_key" ] == "sk-custom-12345"
185+
186+ # Verify that api_base is set for custom endpoint
187+ assert "api_base" in model_kwargs
188+ assert model_kwargs ["api_base" ] == "https://custom-llm.example.com/v1"
189+
190+ # Verify fallback env var is set for OpenAI-compatible endpoints
191+ import os
192+ assert os .environ .get ("OPENAI_API_KEY" ) == "sk-custom-12345"
193+
194+ def test_custom_endpoint_with_literal_api_key (self ):
195+ """Custom endpoint should pass api_key in kwargs when using literal value."""
196+ # Create LLM config for custom endpoint with literal api_key
197+ llm_config = LLMConfig (
198+ models = {
199+ "custom-model" : ModelConfig (
200+ model_name = "custom-model-name" ,
201+ model_url = "https://custom-llm.example.com/v1" ,
202+ api_key = "sk-literal-custom-key"
203+ )
204+ }
205+ )
206+
207+ # Create LiteLLMCaller
208+ caller = LiteLLMCaller (llm_config , debug_mode = True )
209+
210+ # Get model kwargs
211+ model_kwargs = caller ._get_model_kwargs ("custom-model" )
212+
213+ # Verify that api_key is in kwargs (critical for custom endpoints)
214+ assert "api_key" in model_kwargs
215+ assert model_kwargs ["api_key" ] == "sk-literal-custom-key"
216+
217+ # Verify that api_base is set for custom endpoint
218+ assert "api_base" in model_kwargs
219+ assert model_kwargs ["api_base" ] == "https://custom-llm.example.com/v1"
220+
221+ def test_custom_endpoint_with_extra_headers (self , monkeypatch ):
222+ """Custom endpoint should handle extra_headers correctly."""
223+ monkeypatch .setenv ("CUSTOM_API_KEY" , "sk-custom-auth" )
224+ monkeypatch .setenv ("CUSTOM_TENANT" , "tenant-123" )
225+
226+ # Create LLM config for custom endpoint with extra headers
227+ llm_config = LLMConfig (
228+ models = {
229+ "custom-model" : ModelConfig (
230+ model_name = "custom-model-name" ,
231+ model_url = "https://custom-llm.example.com/v1" ,
232+ api_key = "${CUSTOM_API_KEY}" ,
233+ extra_headers = {
234+ "X-Tenant-ID" : "${CUSTOM_TENANT}" ,
235+ "X-Custom-Header" : "custom-value"
236+ }
237+ )
238+ }
239+ )
240+
241+ # Create LiteLLMCaller
242+ caller = LiteLLMCaller (llm_config , debug_mode = True )
243+
244+ # Get model kwargs
245+ model_kwargs = caller ._get_model_kwargs ("custom-model" )
246+
247+ # Verify api_key is passed
248+ assert "api_key" in model_kwargs
249+ assert model_kwargs ["api_key" ] == "sk-custom-auth"
250+
251+ # Verify extra_headers are resolved and passed
252+ assert "extra_headers" in model_kwargs
253+ assert model_kwargs ["extra_headers" ]["X-Tenant-ID" ] == "tenant-123"
254+ assert model_kwargs ["extra_headers" ]["X-Custom-Header" ] == "custom-value"
255+
256+ # Verify api_base is set
257+ assert "api_base" in model_kwargs
258+
259+ def test_known_providers_still_get_api_key_in_kwargs (self ):
260+ """Verify that known providers also get api_key in kwargs (backward compatibility)."""
261+ # Test OpenAI
262+ llm_config = LLMConfig (
263+ models = {
264+ "openai-model" : ModelConfig (
265+ model_name = "gpt-4" ,
266+ model_url = "https://api.openai.com/v1" ,
267+ api_key = "sk-openai-test"
268+ )
269+ }
270+ )
271+ caller = LiteLLMCaller (llm_config , debug_mode = True )
272+ model_kwargs = caller ._get_model_kwargs ("openai-model" )
273+
274+ # OpenAI should get api_key in kwargs
275+ assert "api_key" in model_kwargs
276+ assert model_kwargs ["api_key" ] == "sk-openai-test"
277+
278+ # Test OpenRouter
279+ llm_config = LLMConfig (
280+ models = {
281+ "openrouter-model" : ModelConfig (
282+ model_name = "meta-llama/llama-3-70b" ,
283+ model_url = "https://openrouter.ai/api/v1" ,
284+ api_key = "sk-or-test"
285+ )
286+ }
287+ )
288+ caller = LiteLLMCaller (llm_config , debug_mode = True )
289+ model_kwargs = caller ._get_model_kwargs ("openrouter-model" )
290+
291+ # OpenRouter should get api_key in kwargs
292+ assert "api_key" in model_kwargs
293+ assert model_kwargs ["api_key" ] == "sk-or-test"
0 commit comments