presenton/servers/fastapi/utils/llm_config.py
sudipnext b20199a4e3 feat: Integrate Vertex AI and Azure OpenAI support
- Added environment variables for Vertex AI and Azure OpenAI configurations in docker-compose and user configuration models.
- Updated the application logic to handle Vertex and Azure as new LLM providers, including validation and API key management.
- Enhanced the UI components to support model selection and API key input for Vertex and Azure.
- Updated relevant utility functions and constants to accommodate the new providers.
- Ensured proper error handling for configuration requirements specific to Vertex and Azure.
2026-04-30 06:03:39 +05:45

225 lines
7.6 KiB
Python

import time
from typing import Optional
from fastapi import HTTPException
from llmai.shared import (
AnthropicClientConfig,
AzureOpenAIClientConfig,
ChatGPTClientConfig,
ClientConfig,
GoogleClientConfig,
OpenAIApiType,
OpenAIClientConfig,
VertexAIClientConfig,
)
from enums.llm_provider import LLMProvider
from utils.get_env import (
get_azure_openai_api_key_env,
get_azure_openai_api_version_env,
get_azure_openai_base_url_env,
get_azure_openai_deployment_env,
get_azure_openai_endpoint_env,
get_anthropic_api_key_env,
get_codex_access_token_env,
get_codex_account_id_env,
get_codex_refresh_token_env,
get_codex_token_expires_env,
get_custom_llm_api_key_env,
get_custom_llm_url_env,
get_disable_thinking_env,
get_google_api_key_env,
get_ollama_url_env,
get_openai_api_key_env,
get_vertex_api_key_env,
get_vertex_base_url_env,
get_vertex_location_env,
get_vertex_project_env,
get_web_grounding_env,
)
from utils.llm_provider import get_llm_provider
from utils.parsers import parse_bool_or_none
from utils.set_env import (
set_codex_access_token_env,
set_codex_account_id_env,
set_codex_refresh_token_env,
set_codex_token_expires_env,
)
def enable_web_grounding() -> bool:
return parse_bool_or_none(get_web_grounding_env()) or False
def disable_thinking() -> bool:
return parse_bool_or_none(get_disable_thinking_env()) or False
def _get_codex_access_token() -> str:
access_token = get_codex_access_token_env()
if not access_token:
raise HTTPException(
status_code=400,
detail=(
"Codex OAuth access token is not set. Please authenticate via "
"/api/v1/ppt/codex/auth/initiate"
),
)
expires_str = get_codex_token_expires_env()
if expires_str:
try:
expires_ms = int(expires_str)
now_ms = int(time.time() * 1000)
if now_ms >= expires_ms - 60_000:
refresh_token = get_codex_refresh_token_env()
if refresh_token:
from utils.oauth.openai_codex import (
TokenSuccess,
get_account_id,
refresh_access_token,
)
result = refresh_access_token(refresh_token)
if isinstance(result, TokenSuccess):
set_codex_access_token_env(result.access)
set_codex_refresh_token_env(result.refresh)
set_codex_token_expires_env(str(result.expires))
account_id = get_account_id(result.access)
if account_id:
set_codex_account_id_env(account_id)
access_token = result.access
except (TypeError, ValueError):
pass
return access_token
def get_llm_config() -> ClientConfig:
llm_provider = get_llm_provider()
match llm_provider:
case LLMProvider.OPENAI:
api_key = get_openai_api_key_env()
if not api_key:
raise HTTPException(status_code=400, detail="OpenAI API Key is not set")
return OpenAIClientConfig(
api_key=api_key,
api_type=OpenAIApiType.COMPLETIONS,
)
case LLMProvider.GOOGLE:
api_key = get_google_api_key_env()
if not api_key:
raise HTTPException(status_code=400, detail="Google API Key is not set")
return GoogleClientConfig(api_key=api_key)
case LLMProvider.VERTEX:
api_key = get_vertex_api_key_env()
project = get_vertex_project_env()
location = get_vertex_location_env()
base_url = get_vertex_base_url_env()
if api_key and (project or location):
raise HTTPException(
status_code=400,
detail=(
"Vertex configuration is ambiguous. Configure either "
"VERTEX_API_KEY or VERTEX_PROJECT/VERTEX_LOCATION, not both."
),
)
if api_key:
return VertexAIClientConfig(
api_key=api_key,
base_url=base_url or None,
)
if not project:
raise HTTPException(
status_code=400,
detail=(
"Vertex configuration is incomplete. Set VERTEX_API_KEY "
"or VERTEX_PROJECT (optionally with VERTEX_LOCATION)."
),
)
return VertexAIClientConfig(
project=project,
location=location or None,
base_url=base_url or None,
)
case LLMProvider.AZURE:
api_key = get_azure_openai_api_key_env()
api_version = get_azure_openai_api_version_env()
endpoint = get_azure_openai_endpoint_env()
base_url = get_azure_openai_base_url_env()
deployment = get_azure_openai_deployment_env()
if not api_key:
raise HTTPException(
status_code=400,
detail="Azure OpenAI API Key is not set",
)
if not api_version:
raise HTTPException(
status_code=400,
detail="Azure OpenAI API Version is not set",
)
if not endpoint and not base_url:
raise HTTPException(
status_code=400,
detail=(
"Azure OpenAI endpoint is not set. "
"Configure AZURE_OPENAI_ENDPOINT or AZURE_OPENAI_BASE_URL."
),
)
return AzureOpenAIClientConfig(
api_key=api_key,
api_version=api_version,
endpoint=endpoint or None,
base_url=base_url or None,
deployment=deployment or None,
)
case LLMProvider.ANTHROPIC:
api_key = get_anthropic_api_key_env()
if not api_key:
raise HTTPException(
status_code=400,
detail="Anthropic API Key is not set",
)
return AnthropicClientConfig(api_key=api_key)
case LLMProvider.OLLAMA:
return OpenAIClientConfig(
base_url=(get_ollama_url_env() or "http://localhost:11434") + "/v1",
api_key="ollama",
)
case LLMProvider.CUSTOM:
base_url = get_custom_llm_url_env()
if not base_url:
raise HTTPException(
status_code=400,
detail="Custom LLM URL is not set",
)
return OpenAIClientConfig(
base_url=base_url,
api_key=get_custom_llm_api_key_env() or "null",
)
case LLMProvider.CODEX:
return ChatGPTClientConfig(
access_token=_get_codex_access_token(),
account_id=get_codex_account_id_env() or None,
)
case _:
raise HTTPException(
status_code=400,
detail=(
"LLM Provider must be either openai, google, vertex, azure, "
"anthropic, ollama, custom, or codex"
),
)
def get_extra_body() -> Optional[dict]:
if get_llm_provider() == LLMProvider.CUSTOM and disable_thinking():
return {"enable_thinking": False}
return None