refactor(config): 将配置管理从doppler_config.py迁移到settings.py

This commit is contained in:
ben 2025-08-22 09:11:13 +00:00
parent ed49ef2833
commit 8ba2038293
21 changed files with 167 additions and 26 deletions

View File

@ -110,7 +110,7 @@ liurenchaxin/
## 开发指南 ## 开发指南
### 添加新的AI服务 ### 添加新的AI服务
1. 在 `config/doppler_config.py` 中添加API密钥配置 1. 在 `config/settings.py` 中添加API密钥配置
2. 在 `src/jixia/agents/` 中创建新的代理类 2. 在 `src/jixia/agents/` 中创建新的代理类
3. 在 `src/jixia/engines/` 中添加数据引擎 3. 在 `src/jixia/engines/` 中添加数据引擎
4. 在 `app/tabs/` 中添加界面页签 4. 在 `app/tabs/` 中添加界面页签

View File

@ -10,7 +10,7 @@
- [x] **环境验证**: 基础测试通过,智能体创建成功 - [x] **环境验证**: 基础测试通过,智能体创建成功
#### 2. 配置系统更新 #### 2. 配置系统更新
- [x] **doppler_config.py 增强**: - [x] **settings.py 增强**:
- 新增 `get_google_api_key()` 函数 - 新增 `get_google_api_key()` 函数
- 新增 `get_google_genai_config()` 函数 - 新增 `get_google_genai_config()` 函数
- 更新 `validate_config()` 支持三种模式: - 更新 `validate_config()` 支持三种模式:

View File

@ -43,7 +43,7 @@ liurenchaxin/
│ ├── memory/ # Vertex AI Memory Bank and Cloudflare AutoRAG integration │ ├── memory/ # Vertex AI Memory Bank and Cloudflare AutoRAG integration
│ └── debates/ # Debate logic (including Swarm and ADK) │ └── debates/ # Debate logic (including Swarm and ADK)
├── config/ # Configuration management ├── config/ # Configuration management
│ └── doppler_config.py # Interface for Doppler secrets │ └── settings.py # Interface for Doppler secrets
├── scripts/ # Utility scripts ├── scripts/ # Utility scripts
├── tests/ # Test suite ├── tests/ # Test suite
├── .kiro/ # Kiro AI assistant configuration ├── .kiro/ # Kiro AI assistant configuration
@ -97,7 +97,7 @@ pip install google-adk
Several test and validation scripts exist: Several test and validation scripts exist:
```bash ```bash
# Validate configuration # Validate configuration
python config/doppler_config.py python config/settings.py
# Test API connections (specific script names may vary) # Test API connections (specific script names may vary)
# python scripts/test_*.py # python scripts/test_*.py
@ -122,7 +122,7 @@ python tests/test_*.py
- **Language**: Python 3.x - **Language**: Python 3.x
- **Coding Style**: PEP 8 - **Coding Style**: PEP 8
- **Type Hinting**: Extensive use of type annotations (`typing` module) and `dataclass` for data structures. - **Type Hinting**: Extensive use of type annotations (`typing` module) and `dataclass` for data structures.
- **Configuration**: Centralized configuration management via `config/doppler_config.py`, strictly avoiding hardcoded secrets. - **Configuration**: Centralized configuration management via `config/settings.py`, strictly avoiding hardcoded secrets.
- **Security**: Zero hardcoded keys, environment isolation, automated security scanning. - **Security**: Zero hardcoded keys, environment isolation, automated security scanning.
- **Testing**: Unit tests for core functions, integration tests for API calls, and validation tests for configuration are required. - **Testing**: Unit tests for core functions, integration tests for API calls, and validation tests for configuration are required.
@ -135,7 +135,7 @@ python tests/test_*.py
- `src/jixia/memory/factory.py`: Factory for creating memory backends (Vertex or Cloudflare). - `src/jixia/memory/factory.py`: Factory for creating memory backends (Vertex or Cloudflare).
- `src/jixia/agents/memory_enhanced_agent.py`: Implementation of agents with persistent memory, using Google ADK. - `src/jixia/agents/memory_enhanced_agent.py`: Implementation of agents with persistent memory, using Google ADK.
- `src/jixia/debates/adk_*.py`: Implementations of debate systems using Google ADK. - `src/jixia/debates/adk_*.py`: Implementations of debate systems using Google ADK.
- `config/doppler_config.py`: Central place for accessing configuration and secrets. - `config/settings.py`: Central place for accessing configuration and secrets.
- `requirements.txt`: Python dependencies. - `requirements.txt`: Python dependencies.
- `QUICK_START_GUIDE.md`: Instructions for quick setup and basic usage examples. - `QUICK_START_GUIDE.md`: Instructions for quick setup and basic usage examples.
- `MIGRATION_STATUS.md`: Detailed report on the migration from OpenRouter/Swarm to Google ADK. - `MIGRATION_STATUS.md`: Detailed report on the migration from OpenRouter/Swarm to Google ADK.

View File

@ -27,7 +27,7 @@ liurenchaxin/
│ └── engines/ # 核心引擎 │ └── engines/ # 核心引擎
│ └── perpetual_engine.py # 永动机引擎 │ └── perpetual_engine.py # 永动机引擎
├── config/ # 配置管理 ├── config/ # 配置管理
│ └── doppler_config.py # Doppler配置接口 │ └── settings.py # Doppler配置接口
├── scripts/ # 工具脚本 ├── scripts/ # 工具脚本
│ └── test_openrouter_api.py # API连接测试 │ └── test_openrouter_api.py # API连接测试
├── tests/ # 测试代码 ├── tests/ # 测试代码
@ -111,7 +111,7 @@ pip install git+https://github.com/openai/swarm.git
python scripts/test_openrouter_api.py python scripts/test_openrouter_api.py
# 验证配置 # 验证配置
python config/doppler_config.py python config/settings.py
# 测试Swarm辩论 (可选) # 测试Swarm辩论 (可选)
python src/jixia/debates/swarm_debate.py python src/jixia/debates/swarm_debate.py

View File

@ -90,7 +90,7 @@ def start_jixia_debate():
"""启动稷下学宫辩论""" """启动稷下学宫辩论"""
with st.spinner("正在启动稷下学宫八仙论道..."): with st.spinner("正在启动稷下学宫八仙论道..."):
try: try:
from config.doppler_config import get_rapidapi_key from config.settings import get_rapidapi_key
from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine
api_key = get_rapidapi_key() api_key = get_rapidapi_key()
@ -160,7 +160,7 @@ def main():
# 显示系统统计 # 显示系统统计
try: try:
from config.doppler_config import get_rapidapi_key from config.settings import get_rapidapi_key
from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine
api_key = get_rapidapi_key() api_key = get_rapidapi_key()
@ -194,7 +194,7 @@ def start_debate_session(topic: str):
with st.spinner(f"🏛️ 八仙正在就 {topic} 展开论道..."): with st.spinner(f"🏛️ 八仙正在就 {topic} 展开论道..."):
try: try:
from config.doppler_config import get_rapidapi_key from config.settings import get_rapidapi_key
from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine
from datetime import datetime from datetime import datetime

View File

@ -20,7 +20,7 @@ from dataclasses import dataclass
# 导入配置管理 # 导入配置管理
try: try:
from config.doppler_config import get_rapidapi_key from config.settings import get_rapidapi_key
except ImportError: except ImportError:
# 如果配置模块不可用,使用环境变量 # 如果配置模块不可用,使用环境变量
import os import os

141
config/settings.py Normal file
View File

@ -0,0 +1,141 @@
#!/usr/bin/env python3
"""
项目配置管理模块
从环境变量 (.env) 文件中安全地加载配置和密钥
"""
import os
from typing import Optional, Dict, Any
from pathlib import Path
# 确保 .env 文件在项目根目录被加载
try:
from dotenv import load_dotenv
# 构建到项目根目录的路径 (假设此文件在 config/ 目录下)
env_path = Path(__file__).resolve().parents[1] / '.env'
if env_path.exists():
load_dotenv(dotenv_path=env_path)
else:
print("Warning: .env file not found at project root. Relying on system environment variables.")
except ImportError:
print("Warning: python-dotenv not installed. Relying on system environment variables.")
pass
def get_secret(key: str, default: Optional[str] = None) -> str:
"""
从环境变量获取密钥
Args:
key: 密钥名称
default: 如果未找到密钥则返回的默认值
Returns:
密钥值
Raises:
ValueError: 如果密钥未找到且没有提供默认值
"""
value = os.getenv(key)
if value is not None:
return value
if default is not None:
return default
raise ValueError(f"Required secret '{key}' not found in environment variables. "
"Please ensure it is set in your .env file or system environment.")
def get_rapidapi_key() -> str:
return get_secret('RAPIDAPI_KEY')
def get_openrouter_key() -> str:
return get_secret('OPENROUTER_API_KEY_1')
def get_google_api_key() -> str:
return get_secret('GOOGLE_API_KEY')
def get_google_genai_config() -> Dict[str, Any]:
"""
获取Google GenAI完整配置
"""
use_vertex_ai = get_secret('GOOGLE_GENAI_USE_VERTEXAI', 'FALSE').upper() == 'TRUE'
return {
'api_key': get_secret('GOOGLE_API_KEY', '') if not use_vertex_ai else '',
'use_vertex_ai': use_vertex_ai,
'project_id': get_secret('GOOGLE_CLOUD_PROJECT_ID', ''),
'location': get_secret('GOOGLE_CLOUD_LOCATION', 'us-central1'),
'memory_bank_enabled': get_secret('VERTEX_MEMORY_BANK_ENABLED', 'TRUE').upper() == 'TRUE',
'service_account_key': get_secret('GOOGLE_SERVICE_ACCOUNT_KEY', '')
}
def get_cloudflare_config() -> Dict[str, str]:
"""
获取Cloudflare配置
"""
return {
'account_id': get_secret('CLOUDFLARE_ACCOUNT_ID', ''),
'api_token': get_secret('CLOUDFLARE_API_TOKEN', ''),
'vectorize_index': 'autorag-shy-cherry-f1fb',
'embed_model': '@cf/baai/bge-m3',
'autorag_domain': 'autorag.seekkey.tech'
}
def get_database_config() -> Dict[str, str]:
"""
获取数据库配置
"""
return {
'postgres_url': get_secret('POSTGRES_URL', ''),
'mongodb_url': get_secret('MONGODB_URL', ''),
'zilliz_url': get_secret('ZILLIZ_URL', ''),
'zilliz_token': get_secret('ZILLIZ_TOKEN', '')
}
def validate_config(mode: str = "hybrid") -> bool:
"""
验证必要的配置是否存在
"""
print(f"🔧 Validating configuration for mode: {mode}")
try:
if mode == "openrouter":
get_openrouter_key()
print("✅ OpenRouter configuration is valid.")
elif mode == "google_adk":
config = get_google_genai_config()
if not config['use_vertex_ai']:
get_google_api_key()
else:
if not config['project_id']:
raise ValueError("GOOGLE_CLOUD_PROJECT_ID is required for Vertex AI")
print("✅ Google ADK configuration is valid.")
elif mode == "hybrid":
# In hybrid, we just need at least one to be available
key_found = False
try:
get_openrouter_key()
print("✅ OpenRouter key found.")
key_found = True
except ValueError:
pass # It's ok if this one is missing
try:
google_config = get_google_genai_config()
if not google_config['use_vertex_ai']:
get_google_api_key()
print("✅ Google ADK key found.")
key_found = True
except ValueError:
pass # It's ok if this one is missing
if not key_found:
raise ValueError("In hybrid mode, at least one AI provider key (OpenRouter or Google) must be configured.")
print("✅ Hybrid mode configuration is valid.")
return True
except ValueError as e:
print(f"❌ Configuration validation failed: {e}")
return False
if __name__ == "__main__":
print("🔧 Running configuration validation...")
validate_config()

View File

@ -36,7 +36,7 @@ GOOGLE_SERVICE_ACCOUNT_KEY=path/to/service-account.json # 服务账号密钥
### 1. 验证配置 ### 1. 验证配置
```bash ```bash
# 验证 Google ADK 配置 # 验证 Google ADK 配置
python config/doppler_config.py python config/settings.py
# 测试 Memory Bank 连接 # 测试 Memory Bank 连接
python tests/test_vertex_memory_bank.py python tests/test_vertex_memory_bank.py

View File

@ -82,7 +82,7 @@ doppler secrets set GOOGLE_GENAI_USE_VERTEXAI=TRUE
### 3.1 更新配置管理 ### 3.1 更新配置管理
需要更新 `config/doppler_config.py` 需要更新 `config/settings.py`
```python ```python
def get_google_api_key() -> str: def get_google_api_key() -> str:

View File

@ -62,7 +62,7 @@ liurenchaxin/
│ ├── database/ # 数据库模块 │ ├── database/ # 数据库模块
│ └── api/ # API集成 │ └── api/ # API集成
├── config/ # 配置管理 ├── config/ # 配置管理
│ └── doppler_config.py # Doppler配置 │ └── settings.py # Doppler配置
├── tests/ # 测试代码 ├── tests/ # 测试代码
├── docs/ # 文档 ├── docs/ # 文档
├── scripts/ # 工具脚本 ├── scripts/ # 工具脚本

View File

@ -118,7 +118,7 @@ class JixiaSwarmDebate:
"""获取OpenRouter API密钥""" """获取OpenRouter API密钥"""
# 尝试从配置管理获取 # 尝试从配置管理获取
try: try:
from config.doppler_config import get_openrouter_key from config.settings import get_openrouter_key
return get_openrouter_key() return get_openrouter_key()
except ImportError: except ImportError:
pass pass

View File

@ -12,7 +12,7 @@ import os
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from src.jixia.agents.memory_enhanced_agent import create_memory_enhanced_council from src.jixia.agents.memory_enhanced_agent import create_memory_enhanced_council
from config.doppler_config import validate_config from config.settings import validate_config
async def demo_memory_enhanced_debate(): async def demo_memory_enhanced_debate():

View File

@ -17,7 +17,7 @@
#### **项目结构建议** #### **项目结构建议**
``` ```
doppler://cauldron/ settings.py
├── development/ ├── development/
│ ├── ANTHROPIC_AUTH_TOKEN │ ├── ANTHROPIC_AUTH_TOKEN
│ ├── ANTHROPIC_BASE_URL │ ├── ANTHROPIC_BASE_URL

View File

@ -15,7 +15,7 @@ from typing import Dict, Any, List, Tuple
project_root = os.path.dirname(os.path.abspath(__file__)) project_root = os.path.dirname(os.path.abspath(__file__))
sys.path.insert(0, os.path.join(project_root, 'src')) sys.path.insert(0, os.path.join(project_root, 'src'))
from config.doppler_config import validate_config, get_database_config from config.settings import validate_config, get_database_config
from google.adk import Agent, Runner from google.adk import Agent, Runner
from google.adk.sessions import InMemorySessionService, Session from google.adk.sessions import InMemorySessionService, Session
from google.genai import types from google.genai import types

View File

@ -13,7 +13,7 @@ from pathlib import Path
project_root = Path(__file__).parent.parent project_root = Path(__file__).parent.parent
sys.path.insert(0, str(project_root)) sys.path.insert(0, str(project_root))
from config.doppler_config import get_openrouter_key, get_rapidapi_key from config.settings import get_openrouter_key, get_rapidapi_key
def test_openrouter_api() -> bool: def test_openrouter_api() -> bool:
""" """

View File

@ -21,7 +21,7 @@ except ImportError:
from src.jixia.memory.base_memory_bank import MemoryBankProtocol from src.jixia.memory.base_memory_bank import MemoryBankProtocol
from src.jixia.memory.factory import get_memory_backend from src.jixia.memory.factory import get_memory_backend
from config.doppler_config import get_google_genai_config from config.settings import get_google_genai_config
@dataclass @dataclass

View File

@ -27,7 +27,7 @@ os.environ['GRPC_TRACE'] = ''
# 抑制 warnings # 抑制 warnings
warnings.filterwarnings('ignore') warnings.filterwarnings('ignore')
from config.doppler_config import validate_config from config.settings import validate_config
def check_environment(): def check_environment():

View File

@ -10,7 +10,7 @@ from typing import Dict, List, Optional, Any
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime from datetime import datetime
import aiohttp import aiohttp
from config.doppler_config import get_cloudflare_config from config.settings import get_cloudflare_config
@dataclass @dataclass

View File

@ -19,7 +19,7 @@ except ImportError:
print("⚠️ Google Cloud AI Platform 未安装Memory Bank功能不可用") print("⚠️ Google Cloud AI Platform 未安装Memory Bank功能不可用")
print("安装命令: pip install google-cloud-aiplatform") print("安装命令: pip install google-cloud-aiplatform")
from config.doppler_config import get_google_genai_config from config.settings import get_google_genai_config
@dataclass @dataclass

View File

@ -5,7 +5,7 @@
import os import os
import sys import sys
from config.doppler_config import get_google_genai_config from config.settings import get_google_genai_config
def test_doppler_config(): def test_doppler_config():
"""测试 Doppler 配置""" """测试 Doppler 配置"""

View File

@ -7,7 +7,7 @@ RapidAPI检查工具
import requests import requests
import time import time
from typing import Dict, List, Any from typing import Dict, List, Any
from config.doppler_config import get_rapidapi_key from config.settings import get_rapidapi_key
class RapidAPIChecker: class RapidAPIChecker:
"""RapidAPI服务检查器""" """RapidAPI服务检查器"""