diff --git a/CLAUDE.md b/CLAUDE.md index 5b122d0..517413f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -110,7 +110,7 @@ liurenchaxin/ ## 开发指南 ### 添加新的AI服务 -1. 在 `config/doppler_config.py` 中添加API密钥配置 +1. 在 `config/settings.py` 中添加API密钥配置 2. 在 `src/jixia/agents/` 中创建新的代理类 3. 在 `src/jixia/engines/` 中添加数据引擎 4. 在 `app/tabs/` 中添加界面页签 diff --git a/MIGRATION_STATUS.md b/MIGRATION_STATUS.md index 8a964f1..5eb6b15 100644 --- a/MIGRATION_STATUS.md +++ b/MIGRATION_STATUS.md @@ -10,7 +10,7 @@ - [x] **环境验证**: 基础测试通过,智能体创建成功 #### 2. 配置系统更新 -- [x] **doppler_config.py 增强**: +- [x] **settings.py 增强**: - 新增 `get_google_api_key()` 函数 - 新增 `get_google_genai_config()` 函数 - 更新 `validate_config()` 支持三种模式: diff --git a/QWEN.md b/QWEN.md index d5b877d..22c4b07 100644 --- a/QWEN.md +++ b/QWEN.md @@ -43,7 +43,7 @@ liurenchaxin/ │ ├── memory/ # Vertex AI Memory Bank and Cloudflare AutoRAG integration │ └── debates/ # Debate logic (including Swarm and ADK) ├── config/ # Configuration management -│ └── doppler_config.py # Interface for Doppler secrets +│ └── settings.py # Interface for Doppler secrets ├── scripts/ # Utility scripts ├── tests/ # Test suite ├── .kiro/ # Kiro AI assistant configuration @@ -97,7 +97,7 @@ pip install google-adk Several test and validation scripts exist: ```bash # Validate configuration -python config/doppler_config.py +python config/settings.py # Test API connections (specific script names may vary) # python scripts/test_*.py @@ -122,7 +122,7 @@ python tests/test_*.py - **Language**: Python 3.x - **Coding Style**: PEP 8 - **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. - **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/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. -- `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. - `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. diff --git a/README.md b/README.md index 8367eac..8ca4bcf 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ liurenchaxin/ │ └── engines/ # 核心引擎 │ └── perpetual_engine.py # 永动机引擎 ├── config/ # 配置管理 -│ └── doppler_config.py # Doppler配置接口 +│ └── settings.py # Doppler配置接口 ├── scripts/ # 工具脚本 │ └── test_openrouter_api.py # API连接测试 ├── tests/ # 测试代码 @@ -111,7 +111,7 @@ pip install git+https://github.com/openai/swarm.git python scripts/test_openrouter_api.py # 验证配置 -python config/doppler_config.py +python config/settings.py # 测试Swarm辩论 (可选) python src/jixia/debates/swarm_debate.py diff --git a/app/streamlit_app.py b/app/streamlit_app.py index a7714d0..019f2b2 100644 --- a/app/streamlit_app.py +++ b/app/streamlit_app.py @@ -90,7 +90,7 @@ def start_jixia_debate(): """启动稷下学宫辩论""" with st.spinner("正在启动稷下学宫八仙论道..."): try: - from config.doppler_config import get_rapidapi_key + from config.settings import get_rapidapi_key from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine api_key = get_rapidapi_key() @@ -160,7 +160,7 @@ def main(): # 显示系统统计 try: - from config.doppler_config import get_rapidapi_key + from config.settings import get_rapidapi_key from src.jixia.engines.perpetual_engine import JixiaPerpetualEngine api_key = get_rapidapi_key() @@ -194,7 +194,7 @@ def start_debate_session(topic: str): with st.spinner(f"🏛️ 八仙正在就 {topic} 展开论道..."): 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 datetime import datetime diff --git a/app/tabs/tianxia_tab.py b/app/tabs/tianxia_tab.py index cadac08..2af39ba 100644 --- a/app/tabs/tianxia_tab.py +++ b/app/tabs/tianxia_tab.py @@ -20,7 +20,7 @@ from dataclasses import dataclass # 导入配置管理 try: - from config.doppler_config import get_rapidapi_key + from config.settings import get_rapidapi_key except ImportError: # 如果配置模块不可用,使用环境变量 import os diff --git a/config/settings.py b/config/settings.py new file mode 100644 index 0000000..57c321e --- /dev/null +++ b/config/settings.py @@ -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() diff --git a/docs/VERTEX_MEMORY_BANK_SETUP.md b/docs/VERTEX_MEMORY_BANK_SETUP.md index 17b6a67..51d711d 100644 --- a/docs/VERTEX_MEMORY_BANK_SETUP.md +++ b/docs/VERTEX_MEMORY_BANK_SETUP.md @@ -36,7 +36,7 @@ GOOGLE_SERVICE_ACCOUNT_KEY=path/to/service-account.json # 服务账号密钥 ### 1. 验证配置 ```bash # 验证 Google ADK 配置 -python config/doppler_config.py +python config/settings.py # 测试 Memory Bank 连接 python tests/test_vertex_memory_bank.py diff --git a/docs/guides/GOOGLE_ADK_MIGRATION_GUIDE.md b/docs/guides/GOOGLE_ADK_MIGRATION_GUIDE.md index 4f91c73..a08add0 100644 --- a/docs/guides/GOOGLE_ADK_MIGRATION_GUIDE.md +++ b/docs/guides/GOOGLE_ADK_MIGRATION_GUIDE.md @@ -82,7 +82,7 @@ doppler secrets set GOOGLE_GENAI_USE_VERTEXAI=TRUE ### 3.1 更新配置管理 -需要更新 `config/doppler_config.py`: +需要更新 `config/settings.py`: ```python def get_google_api_key() -> str: diff --git a/docs/guides/MIGRATION_PLAN.md b/docs/guides/MIGRATION_PLAN.md index d2e3f40..5a87a59 100644 --- a/docs/guides/MIGRATION_PLAN.md +++ b/docs/guides/MIGRATION_PLAN.md @@ -62,7 +62,7 @@ liurenchaxin/ │ ├── database/ # 数据库模块 │ └── api/ # API集成 ├── config/ # 配置管理 -│ └── doppler_config.py # Doppler配置 +│ └── settings.py # Doppler配置 ├── tests/ # 测试代码 ├── docs/ # 文档 ├── scripts/ # 工具脚本 diff --git a/examples/debates/swarm_debate_example.py b/examples/debates/swarm_debate_example.py index ea59f9d..25e388d 100644 --- a/examples/debates/swarm_debate_example.py +++ b/examples/debates/swarm_debate_example.py @@ -118,7 +118,7 @@ class JixiaSwarmDebate: """获取OpenRouter API密钥""" # 尝试从配置管理获取 try: - from config.doppler_config import get_openrouter_key + from config.settings import get_openrouter_key return get_openrouter_key() except ImportError: pass diff --git a/examples/memory_bank_demo.py b/examples/memory_bank_demo.py index 4e83451..da1b405 100644 --- a/examples/memory_bank_demo.py +++ b/examples/memory_bank_demo.py @@ -12,7 +12,7 @@ import os 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 config.doppler_config import validate_config +from config.settings import validate_config async def demo_memory_enhanced_debate(): diff --git a/internal/setup/doppler-migration-guide.md b/internal/setup/doppler-migration-guide.md index bb113d0..08ed101 100644 --- a/internal/setup/doppler-migration-guide.md +++ b/internal/setup/doppler-migration-guide.md @@ -17,7 +17,7 @@ #### **项目结构建议** ``` -doppler://cauldron/ +settings.py ├── development/ │ ├── ANTHROPIC_AUTH_TOKEN │ ├── ANTHROPIC_BASE_URL diff --git a/main.py b/main.py index 24b7513..9541fe1 100644 --- a/main.py +++ b/main.py @@ -15,7 +15,7 @@ from typing import Dict, Any, List, Tuple project_root = os.path.dirname(os.path.abspath(__file__)) 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.sessions import InMemorySessionService, Session from google.genai import types diff --git a/scripts/api_health_check.py b/scripts/api_health_check.py index e550bc7..8f53a3b 100644 --- a/scripts/api_health_check.py +++ b/scripts/api_health_check.py @@ -13,7 +13,7 @@ from pathlib import Path project_root = Path(__file__).parent.parent 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: """ diff --git a/src/jixia/agents/memory_enhanced_agent.py b/src/jixia/agents/memory_enhanced_agent.py index 4b30eab..125b8ab 100644 --- a/src/jixia/agents/memory_enhanced_agent.py +++ b/src/jixia/agents/memory_enhanced_agent.py @@ -21,7 +21,7 @@ except ImportError: from src.jixia.memory.base_memory_bank import MemoryBankProtocol 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 diff --git a/src/jixia/main.py b/src/jixia/main.py index aaf5319..cc263fd 100644 --- a/src/jixia/main.py +++ b/src/jixia/main.py @@ -27,7 +27,7 @@ os.environ['GRPC_TRACE'] = '' # 抑制 warnings warnings.filterwarnings('ignore') -from config.doppler_config import validate_config +from config.settings import validate_config def check_environment(): diff --git a/src/jixia/memory/cloudflare_memory_bank.py b/src/jixia/memory/cloudflare_memory_bank.py index 67ef9f2..2c284c6 100644 --- a/src/jixia/memory/cloudflare_memory_bank.py +++ b/src/jixia/memory/cloudflare_memory_bank.py @@ -10,7 +10,7 @@ from typing import Dict, List, Optional, Any from dataclasses import dataclass from datetime import datetime import aiohttp -from config.doppler_config import get_cloudflare_config +from config.settings import get_cloudflare_config @dataclass diff --git a/src/jixia/memory/vertex_memory_bank.py b/src/jixia/memory/vertex_memory_bank.py index b43c603..63e0621 100644 --- a/src/jixia/memory/vertex_memory_bank.py +++ b/src/jixia/memory/vertex_memory_bank.py @@ -19,7 +19,7 @@ except ImportError: print("⚠️ Google Cloud AI Platform 未安装,Memory Bank功能不可用") print("安装命令: pip install google-cloud-aiplatform") -from config.doppler_config import get_google_genai_config +from config.settings import get_google_genai_config @dataclass diff --git a/test_vertex_ai_setup.py b/test_vertex_ai_setup.py index 77ea49c..e714e85 100644 --- a/test_vertex_ai_setup.py +++ b/test_vertex_ai_setup.py @@ -5,7 +5,7 @@ import os import sys -from config.doppler_config import get_google_genai_config +from config.settings import get_google_genai_config def test_doppler_config(): """测试 Doppler 配置""" diff --git a/tools/rapidapi/api_checker.py b/tools/rapidapi/api_checker.py index 0dbf9ad..fbd376e 100644 --- a/tools/rapidapi/api_checker.py +++ b/tools/rapidapi/api_checker.py @@ -7,7 +7,7 @@ RapidAPI检查工具 import requests import time from typing import Dict, List, Any -from config.doppler_config import get_rapidapi_key +from config.settings import get_rapidapi_key class RapidAPIChecker: """RapidAPI服务检查器"""