- 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.
225 lines
7.6 KiB
Python
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
|