Skip to content
36 changes: 0 additions & 36 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -60,39 +60,3 @@ OPENAI_API_KEY=
OPENAI_COMPATIBLE_API_KEY=
OPENAI_COMPATIBLE_BASE_URL=


# ============================================
# Research Agent Configurations
# ============================================
# Email address used for SEC API requests.
# You can set this to any valid email address.
SEC_EMAIL=

# ============================================
# Auto Trading Agent Configurations
# ============================================
# OKX exchange API.
OKX_NETWORK=paper
OKX_API_KEY=
OKX_API_SECRET=
OKX_API_PASSPHRASE=
OKX_ALLOW_LIVE_TRADING=false
OKX_MARGIN_MODE=cash
OKX_USE_SERVER_TIME=false



# ============================================
# Third-Party Agent Configurations
# ============================================
# Finnhub API Key — Required for financial news and insider trading data.
# Get your free API key from: https://finnhub.io/register
# Required by the trading agent.
FINNHUB_API_KEY=


# ============================================
# Additional Configurations
# ============================================
# Optional: Set your https://xueqiu.com/ token if YFinance data fetching becomes unstable.
# XUEQIU_TOKEN=
3 changes: 3 additions & 0 deletions python/configs/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ models:
config_file: "providers/azure.yaml"
api_key_env: "AZURE_OPENAI_API_KEY"
endpoint_env: "AZURE_OPENAI_ENDPOINT"
deepseek:
config_file: "providers/deepseek.yaml"
api_key_env: "DEEPSEEK_API_KEY"

# Agent Configuration
agents:
Expand Down
24 changes: 24 additions & 0 deletions python/configs/providers/deepseek.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# ============================================
# DeepSeek Provider Configuration
# ============================================
name: "DeepSeek"
provider_type: "deepseek"

enabled: true # Default is true if not specified

# Connection Configuration
connection:
base_url: "https://api.deepseek.com/v1"
api_key_env: "DEEPSEEK_API_KEY"

# Default model if none specified
default_model: "deepseek-chat"

# Model Parameters Defaults
defaults:
temperature: 0.7

# Available Models (commonly used)
models:
- id: "deepseek-chat"
name: "DeepSeek Chat"
70 changes: 38 additions & 32 deletions python/configs/providers/openrouter.yaml
Original file line number Diff line number Diff line change
@@ -1,44 +1,50 @@
# ============================================
# OpenRouter Provider Configuration
# ============================================
name: "OpenRouter"
provider_type: "openrouter"
# ============================================
# OpenRouter Provider Configuration
# ============================================
name: "OpenRouter"
provider_type: "openrouter"

enabled: true # Default is true if not specified
enabled: true # Default is true if not specified

# Connection Configuration
connection:
base_url: "https://openrouter.ai/api/v1"
api_key_env: "OPENROUTER_API_KEY"
# Connection Configuration
connection:
base_url: "https://openrouter.ai/api/v1"
api_key_env: "OPENROUTER_API_KEY"

# Default model if none specified
default_model: "anthropic/claude-haiku-4.5"
# Default model if none specified
default_model: "anthropic/claude-haiku-4.5"

# Model Parameters Defaults
defaults:
temperature: 0.5
max_tokens: 4096
# Model Parameters Defaults
defaults:
temperature: 0.5

# Extra headers for OpenRouter API
extra_headers:
HTTP-Referer: "https://valuecell.ai"
X-Title: "ValueCell"
# Extra headers for OpenRouter API
extra_headers:
HTTP-Referer: "https://valuecell.ai"
X-Title: "ValueCell"

# Available Models (commonly used)
models:
# Available Models (commonly used)
models:

- id: "anthropic/claude-haiku-4.5"
name: "Claude Haiku 4.5"
- id: "anthropic/claude-haiku-4.5"
name: "Claude Haiku 4.5"

- id: "x-ai/grok-4"
name: "Grok 4"
- id: "x-ai/grok-4"
name: "Grok 4"

- id: "qwen/qwen-max"
name: "Qwen Max"
- id: "qwen/qwen-max"
name: "Qwen Max"

- id: "openai/gpt-5"
name: "GPT-5"
- id: "openai/gpt-5"
name: "GPT-5"

- id: "google/gemini-2.5-flash"
name: "Gemini 2.5 Flash"

- id: "google/gemini-2.5-pro"
name: "Gemini 2.5 Pro"

# Note: OpenRouter does not support embedding models
# For embedding, use other providers like OpenAI or SiliconFlow etc

# Note: OpenRouter does not support embedding models
# For embedding, use other providers like OpenAI or SiliconFlow etc

33 changes: 29 additions & 4 deletions python/valuecell/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def load_env_file_early() -> None:
"""Load environment variables from .env file at package import time.

Uses python-dotenv for reliable parsing and respects existing environment variables.
Looks for .env file in project root (two levels up from this file).
Looks for .env file in repository root (three levels up from this file).

Note:
- .env file variables override existing environment variables (override=True)
Expand All @@ -34,10 +34,24 @@ def load_env_file_early() -> None:
try:
from dotenv import load_dotenv

# Look for .env file in project root (up 2 levels from this file)
# Look for .env file in repository root (up 3 levels from this file)
current_dir = Path(__file__).parent
project_root = current_dir.parent.parent
project_root = current_dir.parent.parent.parent
env_file = project_root / ".env"
example_file = project_root / ".env.example"

# If .env is missing but .env.example exists, copy it to create .env
if not env_file.exists() and example_file.exists():
try:
import shutil

shutil.copy(example_file, env_file)
if os.getenv("VALUECELL_DEBUG", "false").lower() == "true":
logger.info(f"✓ Created .env by copying .env.example to {env_file}")
except Exception as e:
# Only log errors if debug mode is enabled
if os.getenv("VALUECELL_DEBUG", "false").lower() == "true":
logger.info(f"⚠️ Failed to copy .env.example to .env: {e}")

if env_file.exists():
# Load with override=True to allow .env file to override system variables
Expand Down Expand Up @@ -77,8 +91,19 @@ def _load_env_file_manual() -> None:
"""
try:
current_dir = Path(__file__).parent
project_root = current_dir.parent.parent
project_root = current_dir.parent.parent.parent
env_file = project_root / ".env"
example_file = project_root / ".env.example"

# If .env is missing but .env.example exists, copy it to create .env
if not env_file.exists() and example_file.exists():
try:
import shutil

shutil.copy(example_file, env_file)
except Exception:
# Fail silently to avoid breaking imports
pass

if env_file.exists():
with open(env_file, "r", encoding="utf-8") as f:
Expand Down
Loading