feat: implement api/config endpoint

This commit is contained in:
hetao
2025-06-11 13:51:58 +08:00
parent c187ae511d
commit 8e68c13951
4 changed files with 91 additions and 20 deletions

View File

@@ -7,6 +7,7 @@ import os
from langchain_openai import ChatOpenAI
from langchain_deepseek import ChatDeepSeek
from typing import get_args
from src.config import load_yaml_config
from src.config.agents import LLMType
@@ -15,6 +16,20 @@ from src.config.agents import LLMType
_llm_cache: dict[LLMType, ChatOpenAI] = {}
def _get_config_file_path() -> str:
"""Get the path to the configuration file."""
return str((Path(__file__).parent.parent.parent / "conf.yaml").resolve())
def _get_llm_type_config_keys() -> dict[str, str]:
"""Get mapping of LLM types to their configuration keys."""
return {
"reasoning": "REASONING_MODEL",
"basic": "BASIC_MODEL",
"vision": "VISION_MODEL",
}
def _get_env_llm_conf(llm_type: str) -> Dict[str, Any]:
"""
Get LLM configuration from environment variables.
@@ -33,14 +48,17 @@ def _get_env_llm_conf(llm_type: str) -> Dict[str, Any]:
def _create_llm_use_conf(
llm_type: LLMType, conf: Dict[str, Any]
) -> ChatOpenAI | ChatDeepSeek:
llm_type_map = {
"reasoning": conf.get("REASONING_MODEL", {}),
"basic": conf.get("BASIC_MODEL", {}),
"vision": conf.get("VISION_MODEL", {}),
}
llm_conf = llm_type_map.get(llm_type)
"""Create LLM instance using configuration."""
llm_type_config_keys = _get_llm_type_config_keys()
config_key = llm_type_config_keys.get(llm_type)
if not config_key:
raise ValueError(f"Unknown LLM type: {llm_type}")
llm_conf = conf.get(config_key, {})
if not isinstance(llm_conf, dict):
raise ValueError(f"Invalid LLM Conf: {llm_type}")
raise ValueError(f"Invalid LLM configuration for {llm_type}: {llm_conf}")
# Get configuration from environment variables
env_conf = _get_env_llm_conf(llm_type)
@@ -48,10 +66,10 @@ def _create_llm_use_conf(
merged_conf = {**llm_conf, **env_conf}
if not merged_conf:
raise ValueError(f"Unknown LLM Conf: {llm_type}")
raise ValueError(f"No configuration found for LLM type: {llm_type}")
if llm_type == "reasoning":
merged_conf["api_base"] = merged_conf.pop("base_url")
merged_conf["api_base"] = merged_conf.pop("base_url", None)
return (
ChatOpenAI(**merged_conf)
@@ -69,14 +87,49 @@ def get_llm_by_type(
if llm_type in _llm_cache:
return _llm_cache[llm_type]
conf = load_yaml_config(
str((Path(__file__).parent.parent.parent / "conf.yaml").resolve())
)
conf = load_yaml_config(_get_config_file_path())
llm = _create_llm_use_conf(llm_type, conf)
_llm_cache[llm_type] = llm
return llm
def get_configured_llms() -> dict[str, list[str]]:
"""
Get all configured LLM models grouped by type.
Returns:
Dictionary mapping LLM type to list of configured model names.
"""
try:
conf = load_yaml_config(_get_config_file_path())
llm_type_config_keys = _get_llm_type_config_keys()
configured_llms: dict[str, list[str]] = {}
for llm_type in get_args(LLMType):
# Get configuration from YAML file
config_key = llm_type_config_keys.get(llm_type, "")
yaml_conf = conf.get(config_key, {}) if config_key else {}
# Get configuration from environment variables
env_conf = _get_env_llm_conf(llm_type)
# Merge configurations, with environment variables taking precedence
merged_conf = {**yaml_conf, **env_conf}
# Check if model is configured
model_name = merged_conf.get("model")
if model_name:
configured_llms.setdefault(llm_type, []).append(model_name)
return configured_llms
except Exception as e:
# Log error and return empty dict to avoid breaking the application
print(f"Warning: Failed to load LLM configuration: {e}")
return {}
# In the future, we will use reasoning_llm and vl_llm for different purposes
# reasoning_llm = get_llm_by_type("reasoning")
# vl_llm = get_llm_by_type("vision")