Skip to content

Commit 3b0036f

Browse files
Fix: LLM API Key Error Handling (#427)
* Fix * Feat: Prioritize API Key from Config File Problem: The system was using environment variables for API keys. Solution: Changed the code to first check the config file for API keys. If not found, it falls back to environment variables. Impact: Ensures API keys are managed centrally in the config file, improving flexibility and control. * Update adapter.py * fix: use PR code instead of main branch in workflow Before: Workflow always used main branch code After: Workflow uses PR code when testing PR * Update test_ollama.yml * Update test_ollama.yml * Update test_ollama.yml * Update README: Add AIOS Refresh Command * feat: Add dynamic LLM configuration support in AIOS kernel # Description This PR enables AIOS kernel to dynamically handle LLM configurations from users, allowing: 1. Dynamic API key updates for different LLM providers 2. Runtime configuration refresh without restart 3. Secure API key management ## Changes - Added config update endpoint in kernel - Added configuration refresh mechanism - Updated environment variable handling * Update kernel.py * Fix:LLM API Key Error Handling ## What's Changed - Added proper error handling for invalid API keys - Fixed response parsing for LiteLLM completion calls - Added HTTP status codes for different error types: - 402 for API key issues - 500 for other errors
1 parent c0f2437 commit 3b0036f

File tree

1 file changed

+69
-40
lines changed

1 file changed

+69
-40
lines changed

aios/llm_core/adapter.py

+69-40
Original file line numberDiff line numberDiff line change
@@ -262,53 +262,82 @@ def address_syscall(
262262
temperature (float, optional) : Parameter to control the randomness
263263
of LLM output. Defaults to 0.0.
264264
"""
265-
messages = llm_syscall.query.messages
266-
tools = llm_syscall.query.tools
267-
ret_type = llm_syscall.query.message_return_type
265+
try:
266+
messages = llm_syscall.query.messages
267+
tools = llm_syscall.query.tools
268+
ret_type = llm_syscall.query.message_return_type
268269

269-
llm_syscall.set_status("executing")
270-
llm_syscall.set_start_time(time.time())
270+
llm_syscall.set_status("executing")
271+
llm_syscall.set_start_time(time.time())
271272

272-
restored_context = None
273+
restored_context = None
273274

274-
if self.context_manager:
275-
pid = llm_syscall.get_pid()
276-
if self.context_manager.check_restoration(pid):
277-
restored_context = self.context_manager.gen_recover(pid)
275+
if self.context_manager:
276+
pid = llm_syscall.get_pid()
277+
if self.context_manager.check_restoration(pid):
278+
restored_context = self.context_manager.gen_recover(pid)
278279

279-
if restored_context:
280-
messages += [{
281-
"role": "assistant",
282-
"content": "" + restored_context,
283-
}]
280+
if restored_context:
281+
messages += [{
282+
"role": "assistant",
283+
"content": "" + restored_context,
284+
}]
284285

285-
if tools:
286-
tools = self.pre_process_tools(tools)
287-
messages = self.tool_calling_input_format(messages, tools)
286+
if tools:
287+
tools = self.pre_process_tools(tools)
288+
messages = self.tool_calling_input_format(messages, tools)
288289

289-
model = self.strategy()
290+
model = self.strategy()
290291

291-
if isinstance(model, (str, HfLocalBackend, VLLMLocalBackend, OllamaBackend)):
292-
res = model(
293-
messages=messages,
294-
temperature=temperature,
295-
# tools=tools,
296-
) if not isinstance(model, str) else completion(
297-
model=model,
298-
messages=messages,
299-
temperature=temperature,
300-
# tools=tools,
301-
).choices[0].message.content
302-
else:
303-
raise RuntimeError(f"Unsupported model type: {type(model)}")
292+
if isinstance(model, (str, HfLocalBackend, VLLMLocalBackend, OllamaBackend)):
293+
try:
294+
if isinstance(model, str):
295+
# Extract content correctly when using litellm completion
296+
completion_response = completion(
297+
model=model,
298+
messages=messages,
299+
temperature=temperature,
300+
)
301+
res = completion_response.choices[0].message.content
302+
else:
303+
# Directly call the local backend model
304+
res = model(
305+
messages=messages,
306+
temperature=temperature,
307+
)
308+
except Exception as e:
309+
# Handle API key related errors
310+
if "Invalid API key" in str(e) or "API key not found" in str(e):
311+
return Response(
312+
response_message="Error: Invalid or missing API key for the selected model.",
313+
error=str(e),
314+
finished=True,
315+
status_code=402
316+
)
317+
# Handle other types of errors
318+
return Response(
319+
response_message=f"LLM Error: {str(e)}",
320+
error=str(e),
321+
finished=True,
322+
status_code=500
323+
)
324+
325+
if tools:
326+
if tool_calls := self.parse_tool_calls(res):
327+
return Response(response_message=None,
328+
tool_calls=tool_calls,
329+
finished=True)
304330

305-
if tools:
306-
if tool_calls := self.parse_tool_calls(res):
307-
return Response(response_message=None,
308-
tool_calls=tool_calls,
309-
finished=True)
331+
if ret_type == "json":
332+
res = self.parse_json_format(res)
310333

311-
if ret_type == "json":
312-
res = self.parse_json_format(res)
334+
return Response(response_message=res, finished=True)
313335

314-
return Response(response_message=res, finished=True)
336+
except Exception as e:
337+
# Handle system level errors
338+
return Response(
339+
response_message=f"System Error: {str(e)}",
340+
error=str(e),
341+
finished=True,
342+
status_code=500
343+
)

0 commit comments

Comments
 (0)