Fix key gen again (#12752)

Co-authored-by: openhands <openhands@all-hands.dev>
This commit is contained in:
chuckbutkus
2026-02-05 11:45:10 -05:00
committed by GitHub
parent a1989a40b3
commit 634c2439b4
3 changed files with 28 additions and 16 deletions

View File

@@ -160,17 +160,11 @@ class SaasSettingsStore(SettingsStore):
)
return None
llm_base_url = (
org_member.llm_base_url
if org_member.llm_base_url
else org.default_llm_base_url
)
# Check if provider is OpenHands and generate API key if needed
if self._is_openhands_provider(item):
await self._ensure_api_key(item, str(org_id), openhands_type=True)
elif llm_base_url == LITE_LLM_API_URL:
await self._ensure_api_key(item, str(org_id))
# Check if we need to generate an LLM key.
if item.llm_base_url == LITE_LLM_API_URL:
await self._ensure_api_key(
item, str(org_id), openhands_type=self._is_openhands_provider(item)
)
kwargs = item.model_dump(context={'expose_secrets': True})
for model in (user, org, org_member):

View File

@@ -6,6 +6,8 @@
# Unless you are working on deprecation, please avoid extending this legacy file and consult the V1 codepaths above.
# Tag: Legacy-V0
# This module belongs to the old V0 web server. The V1 application server lives under openhands/app_server/.
import os
from fastapi import APIRouter, Depends, status
from fastapi.responses import JSONResponse
@@ -30,6 +32,10 @@ from openhands.storage.data_models.settings import Settings
from openhands.storage.secrets.secrets_store import SecretsStore
from openhands.storage.settings.settings_store import SettingsStore
LITE_LLM_API_URL = os.environ.get(
'LITE_LLM_API_URL', 'https://llm-proxy.app.all-hands.dev'
)
app = APIRouter(prefix='/api', dependencies=get_dependencies())
@@ -123,8 +129,9 @@ async def store_llm_settings(
settings.llm_api_key = existing_settings.llm_api_key
if settings.llm_model is None:
settings.llm_model = existing_settings.llm_model
if settings.llm_base_url is None:
settings.llm_base_url = existing_settings.llm_base_url
# if llm_base_url is missing or empty, set to default as this only happens for "basic" settings
if not settings.llm_base_url:
settings.llm_base_url = LITE_LLM_API_URL
# Keep search API key if missing or empty
if not settings.search_api_key:
settings.search_api_key = existing_settings.search_api_key

View File

@@ -186,7 +186,12 @@ async def test_store_llm_settings_update_existing():
@pytest.mark.asyncio
async def test_store_llm_settings_partial_update():
"""Test store_llm_settings with partial update."""
"""Test store_llm_settings with partial update.
Note: When llm_base_url is not provided in the update, it gets set to the default
LiteLLM proxy URL. This is intentional behavior for "basic" settings where users
don't specify a custom base URL.
"""
settings = Settings(
llm_model='gpt-4' # Only updating model
)
@@ -200,11 +205,17 @@ async def test_store_llm_settings_partial_update():
result = await store_llm_settings(settings, existing_settings)
# Should return settings with updated model but keep other values
# Should return settings with updated model but keep API key
assert result.llm_model == 'gpt-4'
# For SecretStr objects, we need to compare the secret value
assert result.llm_api_key.get_secret_value() == 'existing-api-key'
assert result.llm_base_url == 'https://existing.example.com'
# When llm_base_url is not provided, it defaults to the LiteLLM proxy URL
import os
expected_base_url = os.environ.get(
'LITE_LLM_API_URL', 'https://llm-proxy.app.all-hands.dev'
)
assert result.llm_base_url == expected_base_url
# Tests for store_provider_tokens