File: README.md
ValueCell
Our Product Launched 🔥🔥🔥
ValueCell now provides A-share deep research, market analysis and requires no deployment—access directly at valuecell.ai.
Description
ValueCell is a community-driven, multi-agent platform for financial applications. Our mission is to build the world's largest decentralized financial agent community.
It provides a team of TOP investment Agents to help you with stock selection, research, tracking, and even trading.
The system keeps all your sensitive information stored locally on your device, ensuring core data security.
Welcome to join our Discord community to share feedback and issues you encounter, and invite more developers to contribute 🔥🔥🔥
Note: ValueCell team members will never proactively contact community participants. This project is for technical exchange only. Investing involves risk. ⚠️
Screenshot
Key Features
Multi-Agent System
- DeepResearch Agent: Automatically retrieve and analyze fundamental documents to generate accurate data insights and interpretable summaries
- Strategy Agent: Supports multiple crypto assets and multi-strategy smart trading, automatically executing your strategies
- News Retrieval Agent: Supports personalized scheduled news delivery to track key information in real time
- Others: More agents are in planning...
Flexible Integrations
- Multiple LLM Providers: Support OpenRouter, SiliconFlow,Azure,Openai-compatible,Google,OpenAI and DeepSeek
- Popular Market Data: Cover US market, Crypto market, Hong Kong market, China market and more
- Multi-Agent Framework Compatible: Support Langchain, Agno by A2A Protocol for research and development integration
- Exchange Connectivity: Live routing to OKX and Binance, featuring built-in guardrails
Quick Start
New Users
To get started quickly, download the latest ValueCell application for MacOS or Windows from the Releases page on GitHub.
After installation, please configure your preferred model provider before using ValueCell for the first time. Refer to the instructions in the application or documentation as needed.
Live Trading
- Configure AI Models: Add your AI Model API Key through the web interface.
- Configure Exchanges: Set up Binance/HyperLiquid/OKX/Coinbase... API credentials
- Create Strategies: Combine AI model with exchange to create custom strategies
- Monitor & Control: Start/stop traders and monitor performance in real-time
- Note: Currently only supports contract trading (spot is implemented as 1X contracts), so please ensure your contract account has sufficient balance
Supported Exchanges
| Exchange | Notes | Status |
|---|---|---|
| Binance | Only supports international site binance.com, not US site. Uses USDT-M futures (USDT-margined contracts). Ensure your futures account has sufficient USDT balance. Trading pair format: BTC/USDT. Note: Ensure perpetual contract account balance is not 0. When applying for API, add IP whitelist by searching My IP in search engine |
✅ Tested |
| Hyperliquid | Only supports USDC as margin currency. Uses your main wallet address + API wallet private key authentication (use API tab to apply). Market orders are automatically converted to IoC limit orders. Trading pair format must be manually adjusted to SYMBOL/USDC (e.g., WIF/USDC). Configure with main wallet address + API wallet private key. Minimum 10U per trade |
✅ Tested |
| OKX | Requires API Key, Secret, and Passphrase (OKX account password) for authentication. Supports USDT-margined contracts. Trading pair format: BTC/USDT |
✅ Tested |
| Coinbase | Supports USDT-margined contracts. Coinbase International is not yet supported | 🟡 Partially Tested |
| Gate.io | Supports USDT-margined contracts. Requires API Key and Secret | 🟡 Partially Tested |
| MEXC | Supports USDT-margined contracts. Requires API Key and Secret | 🟡 Partially Tested |
| Blockchain | Supports USDT-margined contracts. Requires API Key, Secret | 🟡 Partially Tested |
Legend:
- ✅ Tested: Fully tested and verified in production environment
- 🟡 Partially Tested: Code implementation complete but not fully tested, may require debugging
- Recommended: Prioritize using fully tested exchanges (Binance, Hyperliquid, OKX)
Notice
- Currently supports leverage trading only, so you need to ensure your Perps account has sufficient balance.
- You must keep your API secrets secure to avoid losing funds. The app stores secrets locally on your device and will not send them to any third party over the internet.
- To ensure your account safety, you need to reset your API keys regularly.
Note: Before running the application, ensure all prerequisites are installed and environment variables are properly configured. If it has been a long time since the last update, you can delete local data stores and start fresh:
- LanceDB directory (stored in your system application directory, same path as
.env):- macOS:
~/Library/Application Support/ValueCell/lancedb - Linux:
~/.config/valuecell/lancedb - Windows:
%APPDATA%\\ValueCell\\lancedb
- macOS:
- Knowledge directory (stored in your system application directory, same path as
.env):- macOS:
~/Library/Application Support/ValueCell/.knowledge - Linux:
~/.config/valuecell/.knowledge - Windows:
%APPDATA%\\ValueCell\\.knowledge
- macOS:
- SQLite database file (stored in your system application directory, same path as
.env):- macOS:
~/Library/Application Support/ValueCell/valuecell.db - Linux:
~/.config/valuecell/valuecell.db - Windows:
%APPDATA%\\ValueCell\\valuecell.db
- macOS:
Developers
We sincerely invite all developers to join our Discord discussion group, where we regularly share the community roadmap and upcoming contributor benefit plans.
Details on development processes and standards are provided below:CONTRIBUTING.md
ValueCell is a Python-based application with a comprehensive web interface, supporting multi-platform deployment. Follow the configuration below to get started quickly.
Clone Repository
git clone https://github.com/ValueCell-ai/valuecell.git
cd valuecellRunning the Application
Launch the complete application (frontend, backend, and agents):
Linux / Macos
bash start.shWindows (PowerShell)
.\start.ps1Accessing the Interface
- Web UI: Navigate to http://localhost:1420 in your browser
- Logs: View application logs directly in the terminal for detailed runtime information of backend services and individual agents
Next Steps
Once the application is running, you can explore the web interface to interact with ValueCell's features and capabilities.
Configuration
More detailed configuration information can be found at CONFIGURATION_GUIDE
Roadmap
🤖 Enhanced Agent Capabilities
Trading Capabilities
- Crypto: Supports OKX、Binance and Hyperliquid exchanges, with more exchanges planned for integration...
- Securities: Gradually support AI securities trading
Market Expansion
- European Markets: Add support for FTSE, DAX, CAC 40, and other European exchanges
- Asian Markets: Expand coverage to Nikkei and emerging Asian markets
- Commodity Markets: Oil, Gold, Silver, Agricultural products analysis
- Forex Markets: Major currency pairs and cross-currency analysis
Asset Diversification
- Fixed Income: Government bonds, corporate bonds, and yield analysis agents
- Derivatives: Options, futures, and complex financial instruments
- Alternative Investments: Private equity, hedge funds, and venture capital analysis
Advanced Notification & Push Types
- Real-time Alerts: Price movements, volume spikes, and technical breakouts
- Scheduled Reports: Daily/weekly/monthly portfolio summaries
- Event-driven Notifications: Earnings releases, dividend announcements, regulatory changes
- Custom Triggers: User-defined conditions and thresholds
- Multi-channel Delivery: Discord and webhook integrations
⚙️ Product Configuration & Personalization
Multi-platform Products
- Desktop Support: Gradually support desktop and client capabilities
- Database Hot Updates: Gradually support compatibility upgrades
Internationalization (i18n)
- Multi-language Support: English, Chinese (Simplified/Traditional), Japanese, Korean, Spanish, French
- Localized Market Data: Region-specific financial terminology and formats
- Cultural Adaptation: Time zones, date formats, and currency preferences
- Agent Personality Localization: Culturally appropriate communication styles
Token & Authentication Management
- API Key Management: Secure storage and rotation of third-party API keys
- OAuth Integration: Support for major financial data providers
User Preferences & Customization
- Investment Profile: Risk tolerance, investment horizon, and strategy preferences
- UI/UX Customization: Dark/light mode, dashboard layouts, and widget preferences
- Agent Behavior: Communication frequency, analysis depth, and reporting style
- Portfolio Management: Custom benchmarks, performance metrics, and allocation targets
Memory & Learning Systems
- Conversation History: Persistent chat history across sessions
- User Learning: Adaptive recommendations based on user behavior
- Market Memory: Historical context and pattern recognition
- Preference Evolution: Dynamic adjustment of recommendations over time
🔧 ValueCell SDK Development
Core SDK Features
- Python SDK: Comprehensive library for agent integration and customization
- WebSocket Support: Real-time data streaming and bidirectional communication
Agent Integration Framework
- Plugin Architecture: Easy integration of third-party agents and tools
- Agent Registry: Marketplace for community-contributed agents
Developer Tools & Documentation
- Interactive API Explorer: Swagger/OpenAPI documentation with live testing
- Code Examples: Sample implementations in multiple programming languages
- Testing Framework: Unit tests, integration tests, and mock data providers
LICENSE
This project is licensed under the Apache License 2.0 — see the LICENSE file for details.
📌 Note: Apache 2.0 applies only to original code authored by the ValueCell team and contributors. Third-party components (e.g., APIs, widgets, libraries) are governed by their own licenses and terms — see below.
Third-Party Components & Licensing
ValueCell integrates external services and embeds third-party widgets. Their usage is not covered by Apache 2.0, and compliance with their terms is your responsibility as a user/developer.
| Component | Type | License / Terms |
|---|---|---|
| TradingView Advanced Chart | Embedded iframe widget | Free Advanced Charts Agreement (proprietary) |
| Exchange APIs (Binance, OKX, Hyperliquid, etc.) | REST/WebSocket endpoints | Each exchange’s ToS (e.g., Binance API Terms) |
| LLM Providers (OpenAI, Azure, Google, DeepSeek, etc.) | Inference APIs | Provider-specific ToS (e.g., OpenAI ToS) |
Star History
File: docs/CONFIGURATION_GUIDE.md
Configuration Guide
The ValueCell project uses a three-tier configuration system to enable flexible deployment from development to production. This guide covers all aspects of configuring agents, providers, and models.
Configuration Priority
ValueCell resolves configuration from multiple sources in this order (highest to lowest priority):
- Environment Variables - Runtime overrides (e.g.,
OPENROUTER_API_KEY) - .env File - User-level configuration (in project root)
- YAML Files - System defaults (in
python/configs/)
This hierarchy allows you to:
- Set provider credentials via
.envwithout modifying code - Override settings at runtime via environment variables
- Maintain sensible defaults in YAML files
Quick Start
Step 1: Get API Keys
ValueCell supports multiple LLM providers. Choose at least one:
| Provider | Sign Up |
|---|---|
| OpenRouter | openrouter.ai |
| SiliconFlow | siliconflow.cn |
| ai.google.dev | |
| OpenAI | platform.openai.com |
| DashScope | bailian.console.aliyun.com |
Step 2: Configure .env File
Copy the example file and add your API keys:
Edit .env and add your credentials:
In project root
cp .env.example .env
Or SiliconFlow (best for Chinese models and cost)
Edit .env and add your credentials:
Or Google Gemini
GOOGLE_API_KEY=AIzaSyDxxxxxxxxxxxxx
Optional: Set primary provider (auto-detected if not set)
PRIMARY_PROVIDER=openrouter
### Step 3: Launch Application
```bash
# macOS / Linux
bash start.sh
# Windows PowerShell
.\start.ps1The system will auto-detect available providers based on configured API keys.
Note: If you get database compatibility errors, delete these locations:
- LanceDB directory (system application directory, same as
.env):
- macOS:
~/Library/Application Support/ValueCell/lancedb- Linux:
~/.config/valuecell/lancedb- Windows:
%APPDATA%\\ValueCell\\lancedb- Knowledge directory (system application directory, same as
.env):
- macOS:
~/Library/Application Support/ValueCell/.knowledge- Linux:
~/.config/valuecell/.knowledge- Windows:
%APPDATA%\\ValueCell\\.knowledge- SQLite database file (system application directory, same as
.env):
- macOS:
~/Library/Application Support/ValueCell/valuecell.db- Linux:
~/.config/valuecell/valuecell.db- Windows:
%APPDATA%\\ValueCell\\valuecell.db
Configuration System Architecture
File Structure
python/
├── configs/
│ ├── config.yaml # Main configuration
│ ├── config.{environment}.yaml # Environment-specific overrides
│ ├── providers/
│ │ ├── openrouter.yaml # OpenRouter provider config
│ │ ├── siliconflow.yaml # SiliconFlow provider config
│ │ ├── dashscope.yaml # DashScope (Alibaba Cloud) provider config
│ │ └── other_provider.yaml
│ ├── agents/
│ │ ├── super_agent.yaml # Super Agent configuration
│ │ ├── research_agent.yaml # Research Agent configuration
│ │ └── auto_trading_agent.yaml # Auto Trading Agent configuration
│ ├── agent_cards/ # UI metadata for agents
│ └── locales/ # Internationalization files
└── valuecell/
└── config/
├── constants.py # Configuration constants
├── loader.py # YAML loader with env var resolution
└── manager.py # High-level configuration APIHow Configuration Resolution Works
1. Provider Configuration Loading
When the system needs a model, it:
- Loads provider YAML (e.g.,
configs/providers/openrouter.yaml) - Resolves
${VAR}placeholders in YAML using environment variables - Applies env variable overrides (e.g.,
OPENROUTER_API_KEYoverridesconnection.api_key) - Returns ProviderConfig object with resolved values
Example: OpenRouter Configuration
connection:
base_url: "https://openrouter.ai/api/v1"
api_key_env: "OPENROUTER_API_KEY" # Specifies which env var to use
default_model: "anthropic/claude-haiku-4.5"
defaults:
temperature: 0.5
max_tokens: 4096The system automatically reads OPENROUTER_API_KEY from .env or environment.
2. Agent Configuration Loading
When you create an agent (e.g., research_agent), the system:
- Loads agent YAML (e.g.,
configs/agents/research_agent.yaml)
The system automatically readsOPENROUTER_API_KEYfrom.envor environment. - Applies environment variable overrides via
env_overridesmap - Merges with global defaults from
config.yaml - Returns AgentConfig object with complete configuration
Example: Agent Configuration
name: "Research Agent"
enabled: true
models:
primary:
model_id: "google/gemini-2.5-flash"
provider: "openrouter"
provider_models:
siliconflow: "Qwen/Qwen3-235B-A22B-Thinking-2507"
google: "gemini-2.5-flash"
parameters:
temperature: 0.7
env_overrides:
RESEARCH_AGENT_MODEL_ID: "models.primary.model_id"
RESEARCH_AGENT_PROVIDER: "models.primary.provider"This allows runtime overrides:
export RESEARCH_AGENT_MODEL_ID="anthropic/claude-3.5-sonnet"
export RESEARCH_AGENT_PROVIDER="openrouter"
# Now research agent uses Claude 3.5 Sonnet instead of GeminiDetailed Configuration Reference
Global Configuration (`config.yaml`)
The main configuration file sets system-wide defaults:
models:
# Primary provider used if API keys from multiple providers are available
primary_provider: "openrouter"
# Global default parameters (used by all models unless overridden)
defaults:
temperature: 0.5
max_tokens: 4096
# Provider registry
providers:
openrouter:
config_file: "providers/openrouter.yaml"
api_key_env: "OPENROUTER_API_KEY"
siliconflow:
config_file: "providers/siliconflow.yaml"
api_key_env: "SILICONFLOW_API_KEY"
google:
config_file: "providers/google.yaml"
api_key_env: "GOOGLE_API_KEY"
dashscope:
config_file: "providers/dashscope.yaml"
api_key_env: "DASHSCOPE_API_KEY"
# Agent registry
agents:
super_agent:
config_file: "agents/super_agent.yaml"
research_agent:
config_file: "agents/research_agent.yaml"
auto_trading_agent:
config_file: "agents/auto_trading_agent.yaml"Provider Configuration
Each provider has its own YAML file in configs/providers/. Here's the structure:
name: "Provider Display Name"
provider_type: "provider_id" # Used internally
enabled: true # Can be disabled without deleting config
# Connection details
connection:
base_url: "https://api.example.com/v1"
api_key_env: "PROVIDER_API_KEY" # Which env var to read
endpoint_env: "PROVIDER_ENDPOINT" # Optional: for Azure-style endpoints
# Default model when none specified
default_model: "model-id"
# Default parameters for all models from this provider
defaults:
temperature: 0.7
max_tokens: 4096
top_p: 0.95
# List of available models
models:
- id: "model-id-1"
name: "Model Display Name"
context_length: 128000
max_output_tokens: 8192
- id: "model-id-2"
name: "Another Model"
context_length: 256000
# Embedding configuration (optional, not all providers support it)
embedding:
default_model: "embedding-model-id"
defaults:
dimensions: 1536
encoding_format: "float"
models:
- id: "embedding-model-id"
name: "Embedding Model"
dimensions: 1536
max_input: 8192
# Provider-specific configuration
extra_headers:
HTTP-Referer: "https://valuecell.ai"
X-Title: "ValueCell"Agent Configuration
Agent YAML files define how agents should be initialized. Key features:
name: "Agent Display Name"
enabled: true
# Model configuration
models:
# Primary reasoning model
primary:
model_id: "model-id" # Can use provider prefix (e.g., "anthropic/claude-3.5-sonnet")
provider: "openrouter" # Must be explicit (not auto-detected)
# Fallback models for different providers
provider_models:
siliconflow: "qwen/qwen3-max"
google: "gemini-2.5-flash"
# Model-specific parameters (override provider defaults)
parameters:
temperature: 0.8
max_tokens: 8192
# Optional: separate embedding model configuration
embedding:
model_id: "embedding-model-id"
provider: "siliconflow"
provider_models:
google: "gemini-embedding-001"
parameters:
dimensions: 2560
# Map environment variables to config paths for runtime overrides
env_overrides:
# Syntax: ENV_VAR -> config.path.to.value
AGENT_MODEL_ID: "models.primary.model_id"
AGENT_PROVIDER: "models.primary.provider"
AGENT_TEMPERATURE: "models.primary.parameters.temperature"
AGENT_MAX_TOKENS: "models.primary.parameters.max_tokens"
# Embedding configuration
AGENT_EMBEDDER_MODEL: "models.embedding.model_id"
AGENT_EMBEDDER_PROVIDER: "models.embedding.provider"Provider Auto-Detection and Fallback
Auto-Detection
ValueCell automatically selects a primary provider based on available API keys:
Priority order (if multiple providers have API keys):
The selection logic is implemented in python/valuecell/config/manager.py:
- OpenRouter
- SiliconFlow
- OpenAI
- OpenAI-Compatible
- Azure
- Other configured providers (including DashScope, DeepSeek, etc.)
Override this with an environment variable:
export PRIMARY_PROVIDER=siliconflowOr disable auto-detection:
export AUTO_DETECT_PROVIDER=falseFallback Mechanism
If the primary provider fails, ValueCell automatically tries fallback providers.
Fallback chain (auto-populated from enabled providers):
- All providers with valid API keys, except the primary provider
- Stops at first successful model creation
To override fallback providers:
export FALLBACK_PROVIDERS=siliconflow,googleTo disable fallback:
# In agent YAML
use_fallback: falseProvider-Specific Model Mapping
When using fallback, agents can specify which model to use for each provider:
# In agent configuration
models:
primary:
model_id: "anthropic/claude-haiku-4.5"
provider: "openrouter"
# If OpenRouter fails, use these models for fallback providers
provider_models:
siliconflow: "zai-org/GLM-4.6" # Similar capability
google: "gemini-2.5-flash" # Fast and efficientWhen fallback occurs:
- Try OpenRouter with
anthropic/claude-haiku-4.5 - If fails, try SiliconFlow with
zai-org/GLM-4.6 - If fails, try Google with
gemini-2.5-flash
Environment Variables Reference
Global Configuration
# Primary provider selection
PRIMARY_PROVIDER=openrouter
# Auto-detect provider from API keys (default: true)
AUTO_DETECT_PROVIDER=true
# Comma-separated fallback provider chain
FALLBACK_PROVIDERS=siliconflow,google
# Application environment
APP_ENVIRONMENT=productionProvider Credentials
# OpenRouter
OPENROUTER_API_KEY=sk-or-v1-xxxxxxxxxxxxx
# SiliconFlow
SILICONFLOW_API_KEY=sk-xxxxxxxxxxxxx
# Google
GOOGLE_API_KEY=AIzaSyDxxxxxxxxxxxxx
# Azure OpenAI (if using Azure provider)
AZURE_OPENAI_API_KEY=xxxxxxxxxxxxx
AZURE_OPENAI_ENDPOINT=https://xxxxx.openai.azure.com/
OPENAI_API_VERSION=2024-10-21
# DashScope (Alibaba Cloud Qwen3 models)
DASHSCOPE_API_KEY=sk-xxxxxxxxxxxxxModel Configuration
# Global model overrides
PLANNER_MODEL_ID=anthropic/claude-3.5-sonnet
EMBEDDER_MODEL_ID=openai/text-embedding-3-large
# Research Agent
RESEARCH_AGENT_MODEL_ID=google/gemini-2.5-flash
RESEARCH_AGENT_PROVIDER=openrouter
RESEARCH_AGENT_TEMPERATURE=0.8
RESEARCH_AGENT_MAX_TOKENS=8192
EMBEDDER_DIMENSION=3072
# Super Agent
SUPER_AGENT_MODEL_ID=anthropic/claude-haiku-4.5
SUPER_AGENT_PROVIDER=openrouter
# Auto Trading Agent
AUTO_TRADING_AGENT_MODEL_ID=model-id
AUTO_TRADING_AGENT_PROVIDER=openrouterDebugging
# Enable debug logging
AGENT_DEBUG_MODE=trueConfiguration Patterns
Pattern 1: Multi-Model Setup with Fallback
Use case: High availability with cost optimization
# .env file
OPENROUTER_API_KEY=sk-or-v1-xxxxx # Primary: access to many models
SILICONFLOW_API_KEY=sk-xxxxx # Fallback: cost-effective
GOOGLE_API_KEY=AIzaSyD-xxxxx # Second fallback: specialized
DASHSCOPE_API_KEY=sk-xxxxx # DashScope: Qwen3 models (Chinese optimized)
# config.yaml
models:
primary_provider: "openrouter" # Primary (best models)
# Fallback auto-populated as [siliconflow, google]Pattern 2: Specialized Models per Agent
Use case: Optimize each agent for its task
# In research_agent.yaml
models:
primary:
provider: "openrouter"
model_id: "anthropic/claude-3.5-sonnet" # Best for research
embedding:
provider: "siliconflow"
model_id: "Qwen/Qwen3-Embedding-4B" # Best embeddingsPattern 3: Development vs Production
OKX Trading
| Variable | Default | Description |
|---|---|---|
OKX_NETWORK |
paper |
Choose paper for demo trading or mainnet for live environment. |
OKX_API_KEY |
— | OKX API key generated from the OKX console. |
OKX_API_SECRET |
— | API secret corresponding to the key. |
OKX_API_PASSPHRASE |
— | Passphrase set when creating the OKX API key. |
OKX_ALLOW_LIVE_TRADING |
false |
Must be true before routing orders to the mainnet environment. |
OKX_MARGIN_MODE |
cash |
Trading mode passed to OKX (cash, cross, isolated). |
OKX_USE_SERVER_TIME |
false |
Enable to sync with OKX server time for order stamping. |
[!IMPORTANT]
KeepOKX_ALLOW_LIVE_TRADING=falseuntil strategies are validated on the OKX paper environment. Treat API secrets as production credentials and store them in a secure vault.
Troubleshooting
# .env.production
OPENROUTER_API_KEY=sk-or-v1-prod-xxxxx
SILICONFLOW_API_KEY=sk-prod-xxxxx
APP_ENVIRONMENT=productionThen create config.production.yaml with production-specific settings.
Pattern 4: Runtime Overrides
Use case: A/B testing different models without code changes
# Script to test different models
for model in "gpt-4o" "claude-3.5-sonnet" "gemini-2.5-flash"; do
echo "Testing: $model"
RESEARCH_AGENT_MODEL_ID="$model" python your_script.py
doneFor Developers
Configuration System Architecture
The configuration system has three layers:
Loader Layer (
valuecell/config/loader.py)- Reads YAML files
- Resolves
${VAR}placeholders - Applies environment variable overrides
- Implements caching
Manager Layer (
valuecell/config/manager.py)- High-level configuration access
- Provider validation
- Model factory integration
- Fallback chain management
Factory Layer (
valuecell/adapters/models/factory.py)- Creates actual model instances
- Provider-specific implementations
- Parameter merging
- Error handling and fallback
Creating a Model
from valuecell.utils.model import get_model, get_model_for_agent
# Use default configuration
model = get_model("PLANNER_MODEL_ID")
# Override with kwargs
model = get_model("RESEARCH_AGENT_MODEL_ID", temperature=0.9, max_tokens=16384)
# Get agent-specific model
model = get_model_for_agent("research_agent", temperature=0.8)
# Use specific provider
from valuecell.utils.model import create_model_with_provider
model = create_model_with_provider("openrouter", "anthropic/claude-3.5-sonnet")Adding a New Provider
- Create provider YAML (
configs/providers/my_provider.yaml) - Implement provider class in
valuecell/adapters/models/factory.py - Register provider in
ModelFactory._providers - Add to config.yaml provider registry
- Add tests for provider configuration
Best Practices
Set API Keys in .env
- Never commit API keys to version control
- Use
.gitignoreto exclude.env - Use environment variables in CI/CD
Use Provider Fallback
- Configure multiple providers for reliability
- Specify
provider_modelsin agents for consistent fallback - Test fallback behavior before deployment
Monitor Configuration
- Log configuration selection decisions
- Validate configuration on startup
- Alert on missing API keys in production
Version Your Configuration
- Keep agent configurations in version control
- Document why specific models are chosen
- Review configuration changes in code review
Optimize Costs
- Use cheaper models for simple tasks
- Use faster models for real-time applications
- Monitor API usage and set spending limits
Support
For configuration issues or questions:
- Ask on Discord Community
- Report bugs on GitHub Issues
File: docs/CONTRIBUTE_AN_AGENT.md
Contributing an Agent to ValueCell
This guide explains how to build, integrate, and contribute new agents to ValueCell's multi-agent financial platform.
Kickstart 🚀
Want to quickly create a new agent? You can use an AI coding assistant like GitHub Copilot, Cursor, or other Agent Coders to bootstrap your agent automatically!
Simply share this guide with your AI assistant and ask:
"Please create a HelloAgent following this guide."
The AI will read through this documentation and generate all necessary files:
- Agent module (
core.py,__main__.py,__init__.py) - Configuration files (YAML and JSON)
- Agent card registration (JSON)
This is the fastest way to get started and learn the agent structure hands-on!
Table of Contents
- Architecture Overview
- Create a New Agent
- Add an Agent Configuration
- Run Your Agent
- Use Models and Tools
- Event System
- Launch Backend
- Debugging Agent Behavior
Architecture Overview
Understanding the system architecture is crucial for building agents:
- API backend:
valuecell.server(FastAPI/uvicorn). Entry:valuecell.server.main - Agents: Located under
valuecell.agents.<agent_name>with a__main__.pyforpython -mexecution - Core contracts:
valuecell.core.typesdefine response events and data shapes - Streaming helpers:
valuecell.core.agent.streamfor emitting events
For more details, see
Create a New Agent
Creating a new agent involves three core steps:
- Implement the Agent Module - Create the Python module with your agent's logic
- Add Agent Card - Define metadata of agents
- Add Agent Configuration - Configure models parameters
Let's walk through each step in detail.
Step 1: Create Agent Directory Structure
Create a new directory for your agent under python/valuecell/agents/:
mkdir -p python/valuecell/agents/hello_agent
touch python/valuecell/agents/hello_agent/__init__.py
touch python/valuecell/agents/hello_agent/__main__.py
touch python/valuecell/agents/hello_agent/core.pyStep 2: Implement Your Agent Logic
In core.py, subclass BaseAgent and implement the stream() method:
# file: valuecell/agents/hello_agent/core.py
from typing import AsyncGenerator, Optional, Dict
from valuecell.core.types import BaseAgent, StreamResponse
from valuecell.core.agent import streaming
class HelloAgent(BaseAgent):
async def stream(
self,
query: str, # User query content
conversation_id: str, # Conversation ID
task_id: str, # Task ID
dependencies: Optional[Dict] = None, # Optional context (language, timezone, etc.)
) -> AsyncGenerator[StreamResponse, None]:
"""
Process user queries and return streaming responses.
Args:
query: User query content
conversation_id: Unique identifier for the conversation
task_id: Unique identifier for the task
dependencies: Optional dependencies containing language, timezone, and other context
Yields:
StreamResponse: Stream response containing content and completion status
"""
# Send a few chunks, then finish
yield streaming.message_chunk("Thinking…")
yield streaming.message_chunk(f"You said: {query}")
yield streaming.done()Agent Processing Flow Essentials:
- Return Text Content: Use
streaming.message_chunk()to return text responses. You can send complete messages or split them into smaller chunks for better streaming UX. - Signal Completion: Always end with
streaming.done()to indicate the agent has finished processing.
This simple flow enables real-time communication with the UI, displaying responses as they're generated.
Step 3: Add Agent Entry Point
In __main__.py, wrap your agent for standalone execution. This file enables launching your agent with uv run -m:
# file: valuecell/agents/hello_agent/__main__.py
import asyncio
from valuecell.core.agent import create_wrapped_agent
from .core import HelloAgent
if __name__ == "__main__":
agent = create_wrapped_agent(HelloAgent)
asyncio.run(agent.serve())[!IMPORTANT]
Always place the wrap and serve logic in__main__.py. This pattern enables:
- Consistent agent launching via
uv run -m valuecell.agents.your_agent- Automatic discovery by the ValueCell backend server
- Standardized transport and event emission
Run your agent:
cd python
uv run -m valuecell.agents.hello_agent[!TIP]
The wrapper standardizes transport and event emission so your agent integrates with the UI and logs consistently.
Add an Agent Configuration (Required)
Agent configurations define how your agent uses models, embeddings, and runtime parameters. Create a YAML file in python/configs/agents/.
Create Configuration File
Create python/configs/agents/hello_agent.yaml:
name: "Hello Agent"
enabled: true
# Model configuration
models:
# Primary model
primary:
model_id: "anthropic/claude-haiku-4.5"
provider: "openrouter"
# Environment variable overrides
env_overrides:
HELLO_AGENT_MODEL_ID: "models.primary.model_id"
HELLO_AGENT_PROVIDER: "models.primary.provider"[!TIP]
The YAML filename should match your agent's module name (e.g.,hello_agent.yamlforhello_agentmodule). This naming convention helps maintain consistency across the codebase.
For detailed configuration options including embedding models, fallback providers, and advanced patterns, see CONFIGURATION_GUIDE.
Using Configuration in Your Agent
Load your agent's configuration using the config manager. The agent name passed to get_model_for_agent() must match the YAML filename (without the .yaml extension):
from valuecell.utils.model import get_model_for_agent
class HelloAgent(BaseAgent):
def __init__(self, **kwargs):
super().__init__(**kwargs)
# Automatically loads configuration from hello_agent.yaml
# Agent name "hello_agent" must match the YAML filename
self.model = get_model_for_agent("hello_agent")
async def stream(self, query, conversation_id, task_id, dependencies=None):
# Use your configured model
response = await self.model.generate(query)
yield streaming.message_chunk(response)
yield streaming.done()Runtime Configuration Override
You can override configuration via environment variables:
# Override model at runtime
export HELLO_AGENT_MODEL_ID="anthropic/claude-3.5-sonnet"
export HELLO_AGENT_TEMPERATURE="0.9"
# Run your agent with overrides
uv run -m valuecell.agents.hello_agent[!TIP]
For detailed configuration options including embedding models, fallback providers, and advanced patterns, see CONFIGURATION_GUIDE.
Add an Agent Card
Agent Cards declare how your agent is discovered and served. Place a JSON file under:
python/configs/agent_cards/
The name must match your agent class name (e.g., HelloAgent). The url decides the host/port your wrapped agent will bind to.
Minimal Example
{
"name": "HelloAgent",
"url": "http://localhost:10010",
"description": "A minimal example agent that echoes input.",
"capabilities": { "streaming": true, "push_notifications": false },
"default_input_modes": ["text"],
"default_output_modes": ["text"],
"version": "1.0.0",
"skills": [
{
"id": "echo",
"name": "Echo",
"description": "Echo user input back as streaming chunks.",
"tags": ["example", "echo"]
}
]
}[!TIP]
- Filename can be anything (e.g.,
hello_agent.json), butnamemust equal your agent class (used bycreate_wrapped_agent)- Optional
enabled: falsewill disable loading. Extra fields likedisplay_nameormetadataare ignored- Change the
urlport if it's occupied. The wrapper reads host/port from this URL when serving- If you see "No agent configuration found … in agent cards", check the
nameand the JSON location
Run Your Agent
Local Development
For local web development, simply start the backend server which will automatically load all agents:
# Start the full stack (frontend + backend with all agents)
bash start.sh
# Or start backend only
bash start.sh --no-frontendThe backend will automatically discover and initialize your agent based on the agent card configuration.
Direct Agent Execution
You can also run your agent directly using Python module syntax:
cd python
uv run python -m valuecell.agents.hello_agentClient Application
For the packaged client application (Tauri):
- The agent will be automatically included in the build
- No additional registration is required
- Test using workflow builds:
.github/workflows/mac_build.yml
[!TIP]
Environment variables are loaded from system application directory:
- macOS:
~/Library/Application Support/ValueCell/.env- Linux:
~/.config/valuecell/.env- Windows:
%APPDATA%\ValueCell\.envThe
.envfile will be auto-created from.env.exampleon first run if it doesn't exist.
Both local development and packaged client use the same location.
Use Models and Tools Inside an Agent
Agents can use tools to extend their capabilities. Tools are Python functions that the agent can call during execution.
Defining Tools
from agno.agent import Agent
from agno.db.in_memory import InMemoryDb
from valuecell.utils.model import get_model_for_agent
def search_stock_info(ticker: str) -> str:
"""
Search for stock information by ticker symbol.
Args:
ticker: Stock ticker symbol (e.g., "AAPL", "GOOGL")
Returns:
Stock information as a string
"""
# Your tool implementation here
return f"Stock info for {ticker}"
def calculate_metrics(data: dict) -> dict:
"""
Calculate financial metrics from stock data.
Args:
data: Dictionary containing financial data
Returns:
Dictionary with calculated metrics
"""
# Your calculation logic here
return {"pe_ratio": 25.5, "market_cap": "2.5T"}
class MyAgent(BaseAgent):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.inner = Agent(
...
tools=[search_stock_info, calculate_metrics], # Register your tools
...
)Tool Best Practices
- Clear docstrings: Tools should have descriptive docstrings that explain their purpose and parameters
- Type hints: Use type hints for all parameters and return values
- Error handling: Implement proper error handling within tools
- Focused functionality: Each tool should do one thing well
[!TIP]
For more information, refer to Tools - Agno.
Event System (Contracts)
The event system enables real-time communication between agents and the UI. All events are defined in valuecell.core.types.
Stream Events
Events for streaming agent responses:
MESSAGE_CHUNK- A chunk of the agent's response messageTOOL_CALL_STARTED- Agent begins executing a toolTOOL_CALL_COMPLETED- Tool execution finishedCOMPONENT_GENERATOR- Rich format components (charts, tables, reports, etc.)DONE- Indicating the streaming is finished
Component Generator Events
The COMPONENT_GENERATOR event allows agents to send rich UI components beyond plain text. This enables interactive visualizations, structured data displays, and custom widgets.
Supported Component Types:
report- Research reports with formatted contentprofile- Company or stock profilesfiltered_line_chart- Interactive line charts with data filteringfiltered_card_push_notification- Notification cards with filter optionsscheduled_task_controller- UI for managing scheduled tasksscheduled_task_result- Display results of scheduled tasks
Example: Emitting a Component
from valuecell.core.agent import streaming
# Create a line chart component
yield streaming.component_generator(
component_type="filtered_line_chart",
content={
"title": "Stock Price Trends",
"data": [
["Date", "AAPL", "GOOGL", "MSFT"],
["2025-01-01", 150.5, 2800.3, 380.2],
["2025-01-02", 152.1, 2815.7, 382.5],
],
"create_time": "2025-01-15 10:30:00"
}
)
# Create a report component
yield streaming.component_generator(
component_type="report",
content={
"title": "Q4 2024 Financial Analysis",
"data": "## Executive Summary\n\nRevenue increased by 15%...",
"url": "https://example.com/reports/q4-2024",
"create_time": "2025-01-15 10:30:00"
}
)[!TIP]
Component data structures are defined invaluecell.core.types. SeeReportComponentData,FilteredLineChartComponentData, and other component payload classes for required fields.
Emitting Events in Your Agent
Use the streaming.* helpers to emit events. Here's a practical example based on the Research Agent implementation:
from agno.agent import Agent
from valuecell.core.agent import streaming
from valuecell.utils.model import get_model_for_agent
class MyAgent(BaseAgent):
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.inner = Agent(
model=get_model_for_agent("my_agent"),
tools=[...], # your tool functions
# ... other configuration
)
async def stream(self, query, conversation_id, task_id, dependencies=None):
# Stream responses from the inner agent
response_stream = self.inner.arun(
query,
stream=True,
stream_intermediate_steps=True,
session_id=conversation_id,
)
# Process and forward events from the inner agent
async for event in response_stream:
if event.event == "RunContent":
# Emit message chunks as they arrive
yield streaming.message_chunk(event.content)
elif event.event == "ToolCallStarted":
# Notify UI that a tool is being called
yield streaming.tool_call_started(
event.tool.tool_call_id,
event.tool.tool_name
)
elif event.event == "ToolCallCompleted":
# Send tool results back to UI
yield streaming.tool_call_completed(
event.tool.result,
event.tool.tool_call_id,
event.tool.tool_name
)
# Signal completion
yield streaming.done()[!TIP]
Refer to Running Agents - Agno for details
[!TIP]
The UI automatically renders different event types appropriately - messages as text, tool calls with icons, etc. See the complete Research Agent implementation inpython/valuecell/agents/research_agent/core.py.
Launch Backend
Run the API Server
From the python/ folder:
cd python
python -m valuecell.server.mainRun the Agent
Run the Hello Agent as a standalone service:
cd python
python -m valuecell.agents.hello_agent[!TIP]
Set your environment first. At minimum, configureSILICONFLOW_API_KEY(andOPENROUTER_API_KEY) andSEC_EMAIL. See CONFIGURATION_GUIDE.
Optional: setAGENT_DEBUG_MODE=trueto trace model behavior locally.
Debugging Agent Behavior
Use AGENT_DEBUG_MODE to enable verbose traces from agents and planners:
- Logs prompts, tool calls, intermediate steps, and provider response metadata
- Helpful to investigate planning decisions and tool routing during development
Enable in your .env:
AGENT_DEBUG_MODE=true[!CAUTION]
Debug mode can log sensitive inputs/outputs and increases log volume/latency. Enable only in local/dev environments; keep it off in production.
Questions?
If you have questions:
- 💬 Join our Discord
- 📧 Email us at [email protected]
- 🐛 Open an issue for bug reports
Thank you for contributing to ValueCell! 🚀🚀🚀
File: docs/CORE_ARCHITECTURE.md
ValueCell Core Architecture
This document explains how the modules under valuecell/core/ collaborate at runtime.
Highlights
- Super Agent triage ahead of planning: a lightweight "Super Agent" analyzes the user input first and either answers directly or hands off an enriched query to the planner.
- Async, re-entrant orchestrator:
process_user_inputstreams responses and now runs planning/execution in a background producer so long-running work continues even if the client disconnects. - Planner with HITL: pauses on missing info/risky steps via
UserInputRequest, resumes after user feedback to produce an adequate plan. - Streaming pipeline: A2A status events →
ResponseRouter(map to BaseResponse) →ResponseBuffer(annotate/aggregate) → persisted to Store and streamed to UI, with stable item IDs for partial aggregation. - Agent2Agent (A2A) integration: tasks call remote agents via
a2a-sdk; status events drive routing; agents can be wrapped by lightweight decorators/servers. - Conversation memory: in-memory/SQLite stores enable reproducible history, fast "resume from last", and auditability.
- Robustness: typed errors, side-effects (e.g., fail task) from router, and room for retry/backoff policies where appropriate.
Services interaction overview
The diagram below focuses on how the orchestrator collaborates with the core services. It reflects the current code structure under coordinate/, super_agent/, plan/, task/, event/, and conversation/.
flowchart LR
subgraph UI[UI / Client]
end
O[Orchestrator]
CS[ConversationService]
SA[SuperAgentService]
PS[PlanService]
TE[TaskExecutor]
RC[RemoteConnections]
subgraph ES[EventResponseService]
ROuter[event → responses]
RBuf[annotate/aggregate]
end
Store[(Conversation Store)]
%% Entry & conversation lifecycle
UI -->|user_input| O
O -->|ensure/load| CS
%% Super Agent triage
O -->|run| SA
SA -- ANSWER --> O
O -->|emit message| ES
ES --> RBuf
RBuf --> Store
O --> UI
SA -- HANDOFF(enriched) --> PS
%% Planner + HITL
O -->|start_planning_task| PS
PS -- UserInputRequest --> O
O -->|require_user_input / activate| CS
PS -- ExecutionPlan --> O
%% Execution
O -->|execute_plan| TE
TE -->|send_message| RC
RC -- TaskStatusUpdateEvent --> TE
TE -->|route_task_status| ES
ES --> ROuter
ROuter --> ES
ES --> RBuf
RBuf --> Store
O -->|stream annotated responses| UIKey points:
- Orchestrator is the hub: it calls SuperAgentService, PlanService, TaskExecutor, and uses ConversationService to manage statuses.
- EventResponseService performs two roles:
- Routing: maps remote task status events to typed BaseResponses via ResponseRouter.
- Buffering & persistence: annotates with stable item IDs via ResponseBuffer and writes to the conversation store.
- Super Agent can short-circuit with a direct answer; otherwise it hands off an enriched query to the planner.
High-level flow
The orchestration loop ingests a user input, lets the Super Agent triage and possibly answer or enrich the request, then plans next steps (with HITL when needed) and executes tasks via remote agents (A2A). Responses stream back incrementally and are routed to the appropriate sinks (UI, logs, stores).
flowchart TD
U[User Input] --> O[Orchestrator process_user_input]
O --> SA[Super Agent triage]
SA -->|answer directly| SR1[Responses]
SR1 --> RB1[ResponseBuffer]
RB1 --> UI
RB1 --> ST[Store]
SA -->|handoff enriched| P[Planner]
P -->|adequate plan| PL[Plan]
P -->|needs clarification| HITL[HITL: clarification / approval]
HITL --> UI
UI -->|feedback| P
PL --> T[Task Executor]
T --> A2A[A2A calls]
A2A --> RA[Remote Agents]
RA --> RR2[ResponseRouter]
RR2 --> SR2[Responses]
SR2 --> RB2[ResponseBuffer]
RB2 --> UI
RB2 --> ST[Store]Sequence: async and reentrancy
sequenceDiagram
autonumber
participant U as User/UI
participant O as Orchestrator
participant SA as Super Agent
participant CS as ConversationStore/ItemStore
participant P as Planner
participant RB as ResponseBuffer
participant RR as ResponseRouter
participant ST as Store
participant A2A as A2A Client
participant RA as Remote Agent
U->>O: user_input(query, meta)
O->>CS: ensure/load conversation
CS-->>O: context/items
O->>SA: run(user_input)
alt Super Agent answers
SA-->>O: decision=ANSWER, content
O->>RB: annotate/ingest(message)
RB-->>ST: persist SaveItem(s)
O-->>U: stream
O-->>U: done
else Super Agent handoff
SA-->>O: decision=HANDOFF_TO_PLANNER, enriched_query
O->>P: create_plan(enriched_query, callback)
alt needs clarification
P-->>O: UserInputRequest(prompt)
O-->>U: PLAN_REQUIRE_USER_INPUT(prompt)
U->>O: provide_user_input(response)
O->>P: resume with response
end
P-->>O: ExecutionPlan(tasks)
loop each task
O->>A2A: execute(task)
A2A->>RA: request(stream)
RA-->>O: TaskStatusUpdateEvent (streaming)
O->>RR: route(status→responses)
RR-->>O: BaseResponse(s)
O->>RB: annotate/ingest(responses)
RB-->>ST: persist SaveItem(s)
O-->>U: stream to UI
end
O-->>U: done
endOrchestrator: process_user_input
The orchestrator entrypoint (coordinate/orchestrator.py::AgentOrchestrator.process_user_input) receives a user message (plus context IDs) and coordinates the entire lifecycle:
- Delegate to the Super Agent to triage the request: directly answer simple queries or enrich the query and hand off to planning
- Run the Planner to derive an actionable plan; if the plan needs confirmation or extra parameters, trigger Human-in-the-Loop (HITL)
- Execute the plan via the Task Executor
- Stream partial responses while executing
- Persist results and emit final responses
The orchestrator is async and re-entrant, and now decouples producers/consumers:
- All I/O boundaries (
await) are explicit to support concurrency - A background producer continues planning/execution even if the client disconnects; the async generator simply drains a per-call queue
- If a human confirmation is required, the orchestrator can pause, surface a checkpoint, and resume later when feedback arrives
- Reentrancy is supported by idempotent response buffering and conversation state: resuming continues from the last acknowledged step
Streaming model
Responses are produced incrementally while tasks execute:
- Remote agent status events are first mapped by
ResponseRouterinto typedResponseobjects (message chunks, reasoning, tool results, components) ResponseBufferannotates with stable item IDs and aggregates partials, andEventResponseServicepersists them to the conversation store- The orchestrator streams the annotated responses to the UI; persistence and streaming are decoupled from the client connection
This allows the UI to render partial progress while long-running steps (such as remote agent calls) are still in flight.
Super Agent: triage before planning
The Super Agent performs a quick, tool-augmented triage of the user input to decide whether it can answer directly or should hand off to the planner.
Responsibilities:
- Detect simple Q&A or retrieval-style requests that can be answered immediately
- Optionally enrich/normalize the query and provide a concise restatement for planning
- Record minimal rationale for auditability
Under the hood:
super_agent/core.pydefines theSuperAgent, decision schema (SuperAgentOutcome) and tool wiringsuper_agent/prompts.pycontains the instruction and expected output schemasuper_agent/service.pyexposes a simple façade used by the orchestrator
If the decision is ANSWER, the orchestrator streams the content and returns. If the decision is HANDOFF_TO_PLANNER, the enriched query is passed to the planner.
Planner: intent → plan (with HITL)
The Planner turns a natural-language user input (often enriched by the Super Agent) into an executable plan. Its responsibilities include:
- Interpreting the user’s goal and available agent capabilities
- Identifying missing parameters and ambiguities
- Producing a typed plan describing the steps and tool/agent calls
Human-in-the-loop is integrated into planning:
- When the planner detects insufficient information or risky actions, it emits a “clarification/approval” checkpoint
- The orchestrator surfaces that checkpoint via the router to the UI/user
- Once the user adds information or approves the step, the orchestrator resumes with an updated plan context
Under the hood:
plan/planner.pyencapsulates the decision logic (ExecutionPlannerandUserInputRequest)plan/prompts.pycentralizes prompt templates (when LLM-based planning is used)plan/models.pydefines plan/step data models, consumed by the orchestrator and executorplan/service.pymanages the planner lifecycle and the pending user-input registry
Task execution
After planning, the Task Executor runs each task. A task is an atomic unit that typically invokes a remote agent to perform work. Scheduled tasks are supported and can re-run according to their schedule; streaming output is accumulated and summarized for schedule results.
Execution characteristics:
- Tasks are awaited asynchronously; independent tasks may run concurrently when safe
- Each task emits structured responses (tool results, logs, progress) as it runs
- Failures are converted into typed errors and can trigger retries or compensating steps (policy-dependent)
- When the Super Agent hands off to a specific sub-agent, start/end components are emitted to mark that sub-agent conversation window
Under the hood:
task/executor.pystreams execution, integrates scheduled task accumulation, and routes A2A events through the response servicetask/service.pypersists and transitions task state;task/models.pydefine the task’s shape
The conversation and item stores record inputs/outputs for reproducibility and auditing.
A2A integration: talking to remote agents
Each task uses the Agent2Agent (A2A) protocol to interact with remote agents:
- Request/response schemas are defined by the agent capability “cards” and message models
- The local runtime uses
a2a-sdkto send/receive over the selected transport (HTTP or others) - Streaming results are fed into
ResponseBufferand routed live to clients
This protocol boundary makes agents location-transparent: they can run locally, remotely, or be swapped without changing the orchestrator.
Agent implementation: decorators and wiring
Remote agents can be embedded with a very small footprint using the core agent decorator and wiring utilities:
agent/decorator.pywraps a plain async function into a fully-typed agent handleragent/connect.pywires the decorated function into the runtime (registration, routing)agent/card.pydescribes capabilities, inputs, and outputs so the planner can select it
The planner can select this capability when it fits the user’s goal, and the orchestrator will route a task through A2A to execute it.
Conversation and memory
conversation_store.py and item_store.py abstract conversation history and per-item storage:
- In-memory and SQLite backends are available
- Filtering and pagination support efficient context retrieval
- Latest items can be fetched for fast “resume from last” behaviors
This memory layer underpins reentrancy and auditability.
Async & reentrancy details
- All external calls (super-agent triage, planning, remote agents, storage) are awaited
- A background producer runs independently of the client connection; consumers can cancel without stopping execution
ResponseBufferenables idempotent aggregation of partial output so a resumed session can safely replay or continue- Orchestrator checkpoints (HITL) are modeled as explicit yield points; upon resumption, the same context IDs lead the flow to continue from the next step
- Execution contexts support validation (user consistency, TTL) and cleanup of expired sessions
- Backpressure: routers can apply flow control when sinks are slow
Error handling & resilience
Typical edge cases and policies:
- Missing parameters → HITL clarification
- Super Agent errors → surfaced as structured failures; fallback to planner handoff can be policy-defined
- Planner errors → structured failure with user-facing guidance
- Agent timeouts → retry/backoff policies; partial results remain in the buffer
- Transport errors → surfaced via typed exceptions; orchestration may retry or abort
- Invalid or expired execution contexts → cancelled safely with user-facing messages
- Consistency → conversation records ensure inputs/outputs are durable
Extensibility
- Add a new agent: create a capability card, implement a decorated async handler, register/connect it
- Add a new store: implement the
ItemStore/ConversationStoreinterfaces - Add a new transport: integrate a compatible adapter and update the A2A client wiring
- Customize the Super Agent: adjust prompts/decision logic or tools; control when to answer vs handoff
- Customize planning: extend planner prompts/logic and enrich plan models
In short, the orchestrator coordinates an async, re-entrant loop of triage → plan → execute → stream, with human checkpoints where appropriate. The Super Agent can answer or enrich before planning, tasks talk A2A to remote agents, and the response pipeline keeps users informed in real time while maintaining durable, reproducible state.
File: python/valuecell/agents/common/trading/README.md
Trading Agent Framework
This document describes the common trading agent framework: a flexible, composable architecture for building LLM-driven trading strategies with clean separation of concerns and extensible components.
Architecture Overview
The framework provides a base class (BaseStrategyAgent) that handles lifecycle management, streaming, and persistence, while allowing users to customize decision logic and feature computation through well-defined extension points.
Key Principles:
- Separation of Concerns: Data fetching, feature computation, decision making, execution, and history tracking are independent modules
- Extensibility: Override specific components without rewriting the entire pipeline
- Type Safety: Pydantic models ensure data contracts across boundaries
- Async-First: Built on asyncio for efficient I/O and concurrent operations
- Auditable: Each decision cycle has a unique
compose_idfor tracing
Module Layout
common/trading/
├── base_agent.py # BaseStrategyAgent abstract class
├── models.py # Pydantic DTOs and enums
├── constants.py # Default configuration values
├── utils.py # Shared utilities
├── _internal/ # Internal runtime implementation
│ ├── coordinator.py # DefaultDecisionCoordinator
│ ├── runtime.py # StrategyRuntime factory
│ └── stream_controller.py # Persistence and streaming
├── data/ # Market data sources
│ ├── interfaces.py # BaseMarketDataSource
│ └── market.py # SimpleMarketDataSource (CCXT)
├── features/ # Feature computation
│ ├── interfaces.py # BaseFeaturesPipeline, CandleBasedFeatureComputer
│ ├── pipeline.py # DefaultFeaturesPipeline
│ ├── candle.py # SimpleCandleFeatureComputer
│ └── market_snapshot.py # MarketSnapshotFeatureComputer
├── decision/ # Decision composers
│ ├── interfaces.py # BaseComposer
│ └── prompt_based/
│ ├── composer.py # LlmComposer
│ └── system_prompt.py
├── execution/ # Trade execution
│ ├── interfaces.py # BaseExecutionGateway
│ ├── factory.py # Gateway factory
│ ├── paper_trading.py # PaperExecutionGateway
│ └── ccxt_trading.py # CCXTExecutionGateway (live)
├── portfolio/ # Portfolio management
│ ├── interfaces.py # BasePortfolioService
│ └── in_memory.py # InMemoryPortfolioService
└── trading_history/ # History and digest
├── interfaces.py # BaseHistoryRecorder, BaseDigestBuilder
├── recorder.py # InMemoryHistoryRecorder
└── digest.py # RollingDigestBuilderData Flow (Decision Cycle)
Each decision cycle follows this pipeline:
- Portfolio State: Coordinator fetches current
PortfolioView(positions, cash, constraints) - Data Collection: Pipeline pulls market data (candles, tickers, funding rates, etc.)
- Feature Computation: Pipeline computes
FeatureVector[]from raw data - Context Assembly: Coordinator builds
ComposeContextwith features, portfolio, digest, and constraints - Decision: Composer (LLM + guardrails) produces normalized
TradeInstruction[] - Execution: Gateway executes instructions and returns
TxResult[] - Portfolio Update: Service applies trades to update positions and metrics
- History: Recorder checkpoints features, instructions, trades, and summary
- Digest: Builder updates
TradeDigestfor next cycle's context
/* Detailed source-code truncated for AI context efficiency. */Core Data Models
Configuration
UserRequest
llm_model_config: LLMModelConfig— AI model settingsexchange_config: ExchangeConfig— Trading mode, exchange, credentialstrading_config: TradingConfig— Strategy parameters
TradingConfig
strategy_name?: str— Display nameinitial_capital: float— Starting total cash in USDinitial_free_cash: float— Starting free cash in USD (same as initial_capital if there's no initial positions)max_leverage: float— Maximum leverage allowedmax_positions: int— Concurrent position limitsymbols: List[str]— Instruments to trade (e.g.,["BTC-USDT", "ETH-USDT"])decide_interval: int— Seconds between cyclescustom_prompt?: str— Custom strategy promptprompt_text?: str— Additional prompt text
Market Data
Candle
ts: int— Timestamp (milliseconds)instrument: InstrumentRef— Symbol referenceopen, high, low, close, volume: float— OHLCV datainterval: str— Timeframe (e.g., "1m", "1h")
FeatureVector
ts: int— Feature timestampinstrument: InstrumentRef— Associated symbolvalues: Dict[str, float]— Feature key-value pairsmeta?: Dict[str, Any]— Optional metadata (interval, group_by_key, etc.)
Portfolio
PositionSnapshot
instrument: InstrumentRefquantity: float— Signed quantity (+long, -short)avg_price?: float— Average entry pricemark_price?: float— Current market priceunrealized_pnl?: float— Unrealized profit/lossleverage?: float— Applied leverageentry_ts?: int— Entry timestamp
PortfolioView
strategy_id: strts: int— Snapshot timestampaccount_balance: float— Cash balancepositions: Dict[str, PositionSnapshot]— Active positions by symboltotal_value?: float— Portfolio equitytotal_unrealized_pnl?: float— Sum of position unrealized PnLbuying_power?: float— Available buying powerconstraints?: Constraints— Position and leverage limits
Decision
ComposeContext
ts: int— Cycle timestampcompose_id: str— Unique cycle identifierstrategy_id: strfeatures: List[FeatureVector]— Computed featuresportfolio: PortfolioView— Current portfolio statedigest: TradeDigest— Historical performance summary
TradeInstruction
instruction_id: str— Unique instruction IDcompose_id: str— Parent cycle IDinstrument: InstrumentRefside: TradeSide— BUY or SELLquantity: float— Order quantityleverage?: float— Applied leveragemax_slippage_bps?: int— Maximum slippage (basis points)meta?: Dict— Optional metadata
Execution
TxResult
instruction_id: strinstrument: InstrumentRefside: TradeSidestatus: TxStatus— FILLED, PARTIAL, REJECTED, ERRORrequested_qty: floatfilled_qty: floatavg_exec_price?: floatfee_cost?: floatleverage?: float
History
TradeHistoryEntry
trade_id: strcompose_id: str— Originating cycleinstruction_id: str— Originating instructioninstrument: InstrumentRefside: TradeSidetype: TradeType— LONG or SHORTquantity: floatentry_price?, exit_price?: floatentry_ts?, exit_ts?: intrealized_pnl?: float— Profit/loss on closeholding_ms?: int— Position duration
TradeDigest
ts: intby_instrument: Dict[str, TradeDigestEntry]sharpe_ratio?: float— Portfolio Sharpe ratio
TradeDigestEntry (per-symbol stats)
trade_count: intrealized_pnl: floatwin_rate?: floatavg_holding_ms?: intlast_trade_ts?: int
Integration Guide
Quick Start: Using the Default Agent
The simplest way to create a trading agent is to use prompt_strategy_agent, which provides default implementations for all components:
# python/valuecell/agents/prompt_strategy_agent/__main__.py
import asyncio
from valuecell.core.agent import create_wrapped_agent
from .core import StrategyAgent
if __name__ == "__main__":
agent = create_wrapped_agent(StrategyAgent)
asyncio.run(agent.serve())StrategyAgent (in core.py) extends BaseStrategyAgent and uses:
DefaultFeaturesPipeline: Fetches candles and computes technical indicatorsLlmComposer: LLM-based decision making with guardrails
To run:
cd python/valuecell/agents/prompt_strategy_agent
python -m valuecell.agents.prompt_strategy_agentCustom Agent: Override Specific Components
Create a custom agent by subclassing BaseStrategyAgent and overriding extension points:
Example 1: Custom Feature Pipeline
from valuecell.agents.common.trading.base_agent import BaseStrategyAgent
from valuecell.agents.common.trading.features import BaseFeaturesPipeline
from valuecell.agents.common.trading.models import (
FeaturesPipelineResult,
FeatureVector,
UserRequest,
)
class MyFeaturesPipeline(BaseFeaturesPipeline):
"""Custom pipeline with specialized indicators."""
def __init__(self, request: UserRequest):
self.request = request
self.symbols = request.trading_config.symbols
# Initialize custom data sources, indicators, etc.
async def build(self) -> FeaturesPipelineResult:
features = []
# Fetch data and compute custom features
# ... your logic here ...
return FeaturesPipelineResult(features=features)
class MyCustomAgent(BaseStrategyAgent):
"""Agent with custom feature computation."""
async def _build_features_pipeline(
self, request: UserRequest
) -> BaseFeaturesPipeline | None:
return MyFeaturesPipeline(request)
async def _create_decision_composer(self, request: UserRequest):
# Use default LLM composer
return NoneExample 2: Custom Decision Composer
from valuecell.agents.common.trading.decision import BaseComposer
from valuecell.agents.common.trading.models import (
ComposeContext,
ComposeResult,
TradeInstruction,
)
class RuleBasedComposer(BaseComposer):
"""Simple rule-based decision maker (no LLM)."""
def __init__(self, request: UserRequest):
self.request = request
async def compose(self, context: ComposeContext) -> ComposeResult:
instructions = []
# Implement your trading rules
# Example: Buy when RSI < 30, sell when RSI > 70
for fv in context.features:
rsi = fv.values.get("rsi")
if rsi and rsi < 30:
# Create buy instruction
pass
elif rsi and rsi > 70:
# Create sell instruction
pass
return ComposeResult(
instructions=instructions,
rationale="Rule-based signals"
)
class RuleBasedAgent(BaseStrategyAgent):
"""Agent using rule-based decisions."""
async def _build_features_pipeline(self, request: UserRequest):
# Use default pipeline
return None
async def _create_decision_composer(self, request: UserRequest):
return RuleBasedComposer(request)Example 3: Lifecycle Hooks
class MonitoredAgent(BaseStrategyAgent):
"""Agent with custom monitoring and logging."""
async def _on_start(self, runtime, request):
"""Called once after runtime creation."""
self.cycle_count = 0
print(f"Strategy {runtime.strategy_id} starting...")
async def _on_cycle_result(self, result, runtime, request):
"""Called after each cycle completes."""
self.cycle_count += 1
print(f"Cycle {self.cycle_count}: "
f"{len(result.trades)} trades, "
f"PnL: {result.strategy_summary.realized_pnl}")
# Send metrics to external monitoring
# ... custom logic ...
async def _on_stop(self, runtime, request, reason):
"""Called before finalization."""
print(f"Strategy stopping: {reason}")
print(f"Total cycles: {self.cycle_count}")
async def _build_features_pipeline(self, request):
return None # Use defaults
async def _create_decision_composer(self, request):
return None # Use defaultsCreating a Complete Custom Agent Module
Directory Structure:
python/valuecell/agents/my_agent/
├── __init__.py
├── __main__.py # Entry point
├── core.py # Agent implementation
├── features.py # Custom features (optional)
├── composer.py # Custom composer (optional)
└── templates/
└── strategy.txt # Strategy prompt template__main__.py:
import asyncio
from valuecell.core.agent import create_wrapped_agent
from .core import MyAgent
if __name__ == "__main__":
agent = create_wrapped_agent(MyAgent)
asyncio.run(agent.serve())core.py:
from valuecell.agents.common.trading.base_agent import BaseStrategyAgent
from valuecell.agents.common.trading.models import UserRequest
from .features import MyFeaturesPipeline # if custom
from .composer import MyComposer # if custom
class MyAgent(BaseStrategyAgent):
async def _build_features_pipeline(self, request: UserRequest):
# Return custom pipeline or None for default
return MyFeaturesPipeline(request)
async def _create_decision_composer(self, request: UserRequest):
# Return custom composer or None for default
return MyComposer(request)Run your agent:
cd python/valuecell/agents/my_agent
python -m valuecell.agents.my_agentLive Trading Setup
For live trading with real exchanges:
Set trading mode to LIVE:
{
"exchange_config": {
"trading_mode": "live",
"exchange_id": "binance",
"api_key": "YOUR_API_KEY",
"secret_key": "YOUR_SECRET_KEY",
"testnet": true // Use testnet first!
}
}The runtime automatically:
- Fetches real account balance
- Sets
initial_capitalto account total cash - Sets
initial_free_cashto available cash - Uses
CCXTExecutionGatewayfor order submission
Always test on testnet first before using real funds
Testing Strategies
Paper Trading (Default)
{
"exchange_config": {
"trading_mode": "virtual",
"fee_bps": 10.0 // 0.1% simulated fees
}
}Paper trading uses PaperExecutionGateway which:
- Simulates order fills at market price ± slippage
- Applies configurable fees
- No real exchange connection needed
Backtesting
Create a custom BaseMarketDataSource that replays historical data:
from valuecell.agents.common.trading.data import BaseMarketDataSource
from valuecell.agents.common.trading.models import Candle
class BacktestDataSource(BaseMarketDataSource):
def __init__(self, historical_data):
self.data = historical_data
self.current_index = 0
async def get_recent_candles(self, symbols, interval, lookback):
# Return historical candles for current timestamp
candles = self.data[self.current_index]
self.current_index += 1
return candles
async def get_market_snapshot(self, symbols):
# Return snapshot from historical data
return {}Then use it in your custom pipeline.
Extension Points Summary
| Component | Method | Purpose |
|---|---|---|
| Features | _build_features_pipeline() |
Define how market data is fetched and processed |
| Decision | _create_decision_composer() |
Customize trading logic (LLM, rules, ML) |
| Lifecycle | _on_start() |
Initialize resources after runtime creation |
| Lifecycle | _on_cycle_result() |
Monitor/log each cycle result |
| Lifecycle | _on_stop() |
Cleanup before finalization |
Best Practices
- Start with defaults: Use
prompt_strategy_agentas a template - Override incrementally: Only customize what you need
- Type safety: Use Pydantic models for all data contracts
- Async operations: Mark I/O operations as
async - Error handling: Hooks swallow exceptions to prevent crashes
- Testnet first: Always test live trading on testnet
- Monitor carefully: Use lifecycle hooks for observability
Common Patterns
Adding Custom Indicators
class CustomFeaturesPipeline(BaseFeaturesPipeline):
async def build(self):
# Fetch candles
candles = await self.market_data.get_recent_candles(...)
# Compute standard indicators
rsi = compute_rsi(candles)
macd = compute_macd(candles)
# Add custom indicators
my_signal = compute_custom_indicator(candles)
features = []
for symbol in symbols:
features.append(FeatureVector(
ts=timestamp,
instrument=InstrumentRef(symbol=symbol),
values={
"rsi": rsi[symbol],
"macd": macd[symbol],
"custom_signal": my_signal[symbol],
}
))
return FeaturesPipelineResult(features=features)Combining LLM with Rules
class HybridComposer(BaseComposer):
def __init__(self, request):
self.llm_composer = LlmComposer(request)
self.request = request
async def compose(self, context):
# Get LLM suggestions
llm_result = await self.llm_composer.compose(context)
# Apply additional rule filters
filtered_instructions = []
for inst in llm_result.instructions:
if self._passes_risk_check(inst, context):
filtered_instructions.append(inst)
return ComposeResult(
instructions=filtered_instructions,
rationale=f"LLM + risk filters: {llm_result.rationale}"
)
def _passes_risk_check(self, inst, context):
# Custom risk rules
return TrueDebugging
Enable detailed logging:
import logging
from loguru import logger
logger.add("strategy_{time}.log", level="DEBUG")The framework logs:
- Cycle start/end with compose_id
- Instruction count and details
- Execution results and fills
- Portfolio updates
- Error traces with context
Advanced Topics
Custom Execution Gateway
Implement BaseExecutionGateway to integrate custom execution logic:
from valuecell.agents.common.trading.execution import BaseExecutionGateway
from valuecell.agents.common.trading.models import (
TradeInstruction,
TxResult,
TxStatus,
)
class MyExecutionGateway(BaseExecutionGateway):
async def execute(self, instructions, market_features):
results = []
for inst in instructions:
# Your execution logic
result = TxResult(
instruction_id=inst.instruction_id,
instrument=inst.instrument,
side=inst.side,
status=TxStatus.FILLED,
requested_qty=inst.quantity,
filled_qty=inst.quantity,
avg_exec_price=100.0, # from your system
)
results.append(result)
return resultsCustom Portfolio Service
Override portfolio management for complex accounting:
from valuecell.agents.common.trading.portfolio import BasePortfolioService
class CustomPortfolioService(BasePortfolioService):
def get_view(self):
# Return custom PortfolioView
pass
def apply_trades(self, trades, market_features):
# Update internal state
passPersistence Integration
Use StreamController to persist strategy state to your database. The framework already handles:
- Initial portfolio snapshot
- Cycle results (compose cycles, instructions, execution details)
- Final cleanup and status updates
See _internal/stream_controller.py for persistence logic.
File: python/valuecell/server/db/README.md
ValueCell Database Initialization
This directory contains database-related code for ValueCell Server, including model definitions, connection management, and initialization scripts.
Directory Structure
db/
├── __init__.py # Database package initialization
├── connection.py # Database connection and session management
├── init_db.py # Database initialization script
├── models/ # Database models
│ ├── __init__.py
│ ├── base.py # Base model class
│ ├── agent.py # Agent model
│ └── asset.py # Asset model
└── README.md # This documentDatabase Configuration
Database configuration is defined in valuecell/server/config/settings.py:
VALUECELL_DATABASE_URL: Database connection URL. Defaults to a SQLite file under the system application directory (same place as.env):- macOS:
sqlite:///~/Library/Application Support/ValueCell/valuecell.db - Linux:
sqlite:///~/.config/valuecell/valuecell.db - Windows:
sqlite:///%APPDATA%/ValueCell/valuecell.db
- macOS:
DB_ECHO: Whether to output SQL logs, defaults tofalse
Database Models
Agent Model (Agent)
The Agent model stores information about all available AI agents in the ValueCell system:
Basic Information:
name: Unique agent identifierdisplay_name: Human-readable display namedescription: Detailed description of agent functionality and purposeversion: Agent version number
State Management:
enabled: Whether the agent is enabledis_active: Whether the agent is active and available
Functionality:
capabilities: JSON format capability description (e.g., streaming, push notifications)agent_metadata: Additional metadata (author, tags, supported features, etc.)config: Agent-specific configuration parameters
Timestamps:
created_at: Creation timeupdated_at: Update time
Asset Model (Asset)
The Asset model represents financial assets in the ValueCell system, including stocks, bonds, cryptocurrencies, and other investment instruments.
Key fields:
id: Primary key (auto-increment)symbol: Unique asset symbol/ticker (e.g., "AAPL", "BTC-USD")name: Full name of the assetdescription: Detailed description of the assetasset_type: Type of asset (stock, bond, crypto, commodity, etc.)sector: Industry sector (for stocks)current_price: Current market priceis_active: Whether the asset is activeasset_metadata: Additional metadata (fundamental data, tags, etc.)config: Asset-specific configuration parameterscreated_at: Timestamp when the asset was createdupdated_at: Timestamp when the asset was last updated
Database Initialization
Usage
Basic initialization:
bashcd /path/to/valuecell/python python3 -m valuecell.server.db.init_dbForce re-initialization:
bashpython3 -m valuecell.server.db.init_db --forceVerbose logging:
bashpython3 -m valuecell.server.db.init_db --verboseUsing standalone script:
bashpython3 scripts/init_database.py
Initialization Process
- Check database file: Verify if SQLite database file exists
- Create database file: Create new database file if it doesn't exist
- Create table structure: Create agents and assets tables based on model definitions
- Initialize default data:
- Agent data: Insert default Agent records directly from code
- Create three default agents: AIHedgeFundAgent, Sec13FundAgent, and TradingAgents
- Support updating existing Agent configuration information
- Asset data: Insert default Asset records for common financial instruments
- Create default assets: AAPL, GOOGL, MSFT, SPY, BTC-USD
- Support updating existing Asset information
- Agent data: Insert default Agent records directly from code
- Verify initialization: Confirm database connection and table structure are correct
Default Records
The initialization script automatically creates default records directly in the code:
Default Agents
Default agents created:
- AIHedgeFundAgent: AI-powered hedge fund analysis and trading agent
- Sec13FundAgent: SEC 13F fund analysis and tracking agent
- TradingAgents: Multi-agent trading analysis system with market, sentiment, news and fundamentals analysis
Default Assets
Default assets created:
- AAPL: Apple Inc. (Technology stock)
- GOOGL: Alphabet Inc. Class A (Technology stock)
- MSFT: Microsoft Corporation (Technology stock)
- SPY: SPDR S&P 500 ETF Trust (Index ETF)
- BTC-USD: Bitcoin (Cryptocurrency)
Agent data structure example:
{
"name": "TradingAgents",
"display_name": "Trading Agents Adapter",
"description": "TradingAgents - Multi-agent trading analysis system",
"version": "1.0.0",
"enabled": True,
"is_active": True,
"capabilities": {
"streaming": True,
"push_notifications": False
},
"metadata": {
"version": "1.0.0",
"author": "ValueCell Team",
"tags": ["trading", "analysis", "multi-agent"],
"supported_tickers": ["AAPL", "GOOGL", "MSFT"],
"supported_analysts": ["market", "social", "news"]
}
}Asset data structure example:
{
"symbol": "AAPL",
"name": "Apple Inc.",
"asset_type": "stock",
"sector": "Technology",
"is_active": True,
"metadata": {
"market_cap": "large",
"dividend_yield": 0.5,
"beta": 1.2,
"tags": ["blue-chip", "dividend", "growth"]
}
}Usage in Code
Getting Database Session
from valuecell.server.db import get_db, Agent, Asset
# Using dependency injection in FastAPI routes
@app.get("/api/agents")
def get_agents(db: Session = Depends(get_db)):
return db.query(Agent).filter(Agent.enabled == True).all()
@app.get("/api/assets")
def get_assets(db: Session = Depends(get_db)):
return db.query(Asset).filter(Asset.is_active == True).all()Direct Database Manager Usage
from valuecell.server.db import get_database_manager, Agent
db_manager = get_database_manager()
session = db_manager.get_session()
try:
# Get all enabled agents
agents = session.query(Agent).filter(Agent.enabled == True).all()
# Get specific agent
trading_agent = session.query(Agent).filter(Agent.name == "TradingAgents").first()
# Update agent status
if trading_agent:
trading_agent.is_active = True
session.commit()
finally:
session.close()Programmatic Initialization
from valuecell.server.db import init_database
# Initialize database
success = init_database(force=False)
if success:
print("Database initialization successful")
else:
print("Database initialization failed")Important Notes
- Password Security: Default admin user password is a placeholder and should be replaced with proper hashed password in production environment
- Database Backup: SQLite database file should be backed up regularly
- Permission Management: Ensure database file has appropriate filesystem permissions
- Environment Variables: Database connection can be customized through
VALUECELL_DATABASE_URLenvironment variable
Troubleshooting
Common Issues
- Permission Error: Ensure write permissions to database file directory
- Module Import Error: Ensure running in correct Python environment
- Database Lock: Ensure no other processes are using the database file
Reset Database
If you need to completely reset the database:
# Delete existing database file (choose your OS path)
# macOS
rm -f "$HOME/Library/Application Support/ValueCell/valuecell.db"
# Linux
rm -f "$HOME/.config/valuecell/valuecell.db"
# Windows (PowerShell)
Remove-Item "$env:APPDATA\ValueCell\valuecell.db" -ErrorAction SilentlyContinue
# Re-initialize
python3 -m valuecell.server.db.init_dbOr use force re-initialization:
python3 -m valuecell.server.db.init_db --forceFile: python/README.md
ValueCell Python Package
A community-driven, multi-agent platform for financial applications — typed, async-first, and built for orchestration.
Highlights
- Async, re-entrant orchestrator: streaming
process_user_inputcan pause for human-in-the-loop (HITL) and resume safely. - Planner with HITL: pauses on missing info/risky steps via async
UserInputRequest, resumes after user feedback to produce an adequate plan. - Streaming pipeline:
Response→ResponseBuffer(buffered vs immediate with stable item_id) →ResponseRouterto UI and Store. - Agent2Agent (A2A) integration: first-class support via a2a-sdk for agent-to-agent protocols, message schemas, and optional HTTP server interop.
- Conversation memory: in-memory/SQLite stores enable reproducible history, fast "resume from last", and auditability.
- Robustness & extensibility: typed events/errors, router side-effects (e.g., fail task), and clear seams to add agents, stores, transports, and planner logic.
See detailed flow diagrams and design notes in ../docs/CORE_ARCHITECTURE.md.
Quickstart
Set up the environment and verify your install:
uv sync --group dev
uv run python -c "import valuecell as vc; print(vc.__version__)"Installation
Development Installation
Install the package in development mode with all dependencies (including testing tools like pytest, pytest-cov, and diff-cover):
uv sync --group devProduction Installation
uv syncRequirements
- Python >= 3.12
- Dependencies managed via
pyproject.toml
OKX Trading (Preview)
Add OKX credentials to .env (or export them before launch):
AUTO_TRADING_EXCHANGE=okx
OKX_NETWORK=paper # switch to mainnet only after validation
OKX_API_KEY=...
OKX_API_SECRET=...
OKX_API_PASSPHRASE=...
OKX_ALLOW_LIVE_TRADING=false
OKX_MARGIN_MODE=cash # or cross / isolatedLaunch with ./start.sh --exchange okx --network paper to route the Auto Trading agent through OKX. Flip OKX_ALLOW_LIVE_TRADING=true only when you're ready for real execution.
File: README.ja.md
ValueCell
プロダクト公開 🔥🔥🔥
ValueCell は A 株のディープリサーチと市場分析を提供し、デプロイ不要で valuecell.ai から直接利用できます。
概要
ValueCell は、金融アプリケーション向けのコミュニティ主導型マルチエージェントプラットフォームです。私たちの使命は、世界最大の分散型金融エージェントコミュニティを構築することです。
トップクラスの投資エージェントチームが、銘柄選別、リサーチ、追跡、さらには取引まで支援します。
機密情報はすべてローカルデバイスに保存され、コアデータのセキュリティを確保します。
Discord コミュニティへのご参加をお待ちしています。使用中に発生した問題についてのご意見をお寄せいただき、さらに多くの開発者にご参加いただけますようお願いします 🔥🔥🔥
注意: ValueCellチームメンバーがコミュニティ参加者に主動的に連絡することはありません。このプロジェクトは技術交流のみを目的としています。投資にはリスクが伴います。⚠️
スクリーンショット
主な機能
マルチエージェントシステム
- DeepResearch Agent: 株式の基本情報ドキュメントを自動的に取得・分析し、正確なデータインサイトと解釈可能なサマリーを生成
- Strategy Agent: 複数の暗号資産とマルチ戦略のスマート取引に対応し、あなたの戦略を自動実行します
- News Retrieval Agent: パーソナライズされた定時ニュース配信に対応し、重要情報をタイムリーに追跡します
- その他: さらに多くのエージェントを計画中...
柔軟な統合
- 複数のLLMプロバイダー: OpenRouter、SiliconFlow、Azure、Openai-compatible、Google、OpenAIおよびDeepSeekをサポート
- 人気の市場データ: 米国市場、暗号市場、香港市場、中国市場など
- マルチエージェントフレームワーク対応: A2AプロトコルによるLangchain、Agnoをサポート、研究開発の統合を行う
- 取引所接続: OKX と Binance へのリアルタイムルーティングに対応し、安全ガードレールを内蔵
クイックスタート
新規ユーザー向け
最新の ValueCell アプリケーション(MacOS または Windows 用)を GitHub のリリースページからダウンロードできます。
インストール後、初回使用時に、お好みのモデルプロバイダーを設定してください。アプリケーション内の指示またはドキュメントを参照してください。
ライブ取引
- AIモデルの設定: Webインターフェースから AI モデルの API キーを追加します。
- 取引所の設定: Binance/HyperLiquid/OKX/Coinbase... の API 認証情報を設定します。
- ストラテジー作成: AIモデルと取引所を組み合わせてカスタム戦略を作成します。
- モニタリング&コントロール: 戦略の開始/停止を行い、パフォーマンスをリアルタイムで監視します。
- 注意:現在は先物取引のみをサポートしています(現物は1X先物として実装)。先物口座に十分な残高があることを確認してください
サポートされている取引所
| 取引所 | 備考 | ステータス |
|---|---|---|
| Binance | 国際サイト binance.com のみサポート(米国サイトは非対応)。USDT-M 先物(USDT証拠金契約)を使用します。先物口座に十分な USDT 残高があることを確認してください。取引ペア形式: BTC/USDT。注意:無期限先物口座の残高が0でないことを確認してください。API申請時はIPホワイトリストを追加してください(検索エンジンでMy IPを検索して確認) |
✅ テスト済み |
| Hyperliquid | 証拠金通貨として USDC のみサポートします。メインウォレットアドレス + API ウォレット秘密鍵認証を使用します(APIタブから申請)。成行注文は自動的に IoC 指値注文に変換されます。取引ペア形式は手動で SYMBOL/USDC に調整する必要があります(例: WIF/USDC)。メインウォレットアドレス+APIウォレット秘密鍵で設定。1取引あたり最低10U |
✅ テスト済み |
| OKX | 認証には API Key、Secret、Passphrase(OKXアカウントパスワード)が必要です。USDT証拠金契約をサポートします。取引ペア形式: BTC/USDT |
✅ テスト済み |
| Coinbase | USDT証拠金契約をサポートします。Coinbase International はまだサポートされていません。 | 🟡 部分的にテスト済み |
| Gate.io | USDT証拠金契約をサポートします。API Key と Secret が必要です。 | 🟡 部分的にテスト済み |
| MEXC | USDT証拠金契約をサポートします。API Key と Secret が必要です。 | 🟡 部分的にテスト済み |
| Blockchain | USDT証拠金契約をサポートします。API Key と Secret が必要です。 | 🟡 部分的にテスト済み |
凡例:
- ✅ テスト済み: 本番環境で完全にテストおよび検証済み
- 🟡 部分的にテスト済み: コードの実装は完了していますが、完全にはテストされておらず、デバッグが必要な場合があります
- 推奨: 完全にテストされた取引所(Binance, Hyperliquid, OKX)を優先的に使用してください
注意事項
- 現在はレバレッジ取引のみをサポートしているため、Perps(無期限先物)アカウントに十分な残高があることを確認する必要があります。
- 資金の損失を防ぐため、API シークレットは安全に保管する必要があります。アプリはシークレットをデバイス上にローカルに保存し、インターネット経由で第三者に送信することはありません。
- アカウントの安全を確保するために、API キーを定期的にリセットする必要があります。
注意: アプリケーションを実行する前に、すべての前提条件がインストールされ、環境変数が適切に設定されていることを確認してください。
長期間更新がない場合は、ローカルデータを削除して再起動できます:
- LanceDB ディレクトリ(システムアプリディレクトリに保存。
.envと同じ場所):- macOS:
~/Library/Application Support/ValueCell/lancedb - Linux:
~/.config/valuecell/lancedb - Windows:
%APPDATA%\\ValueCell\\lancedb
- macOS:
- Knowledge ディレクトリ(システムアプリディレクトリに保存。
.envと同じ場所):- macOS:
~/Library/Application Support/ValueCell/.knowledge - Linux:
~/.config/valuecell/.knowledge - Windows:
%APPDATA%\\ValueCell\\.knowledge
- macOS:
- SQLite データベースファイル(システムアプリディレクトリに保存。
.envと同じ場所):- macOS:
~/Library/Application Support/ValueCell/valuecell.db - Linux:
~/.config/valuecell/valuecell.db - Windows:
%APPDATA%\\ValueCell\\valuecell.db
- macOS:
開発者
すべての開発者をDiscordディスカッショングループに招待し、コミュニティのRoadMapと将来のコミュニティコントリビューター権利計画について定期的に交流します
開発プロセスと標準の詳細については、CONTRIBUTING.mdを参照してください
ValueCellは包括的なWebインターフェースを備えたPythonベースのアプリケーションで、マルチプラットフォーム展開をサポートしています。以下の設定に従って、すぐに始めることができます。
リポジトリのクローン
git clone https://github.com/ValueCell-ai/valuecell.git
cd valuecellアプリケーションの実行
完全なアプリケーション(フロントエンド、バックエンド、エージェント)を起動します:
Linux / Macos
bash start.shWindows (PowerShell)
.\start.ps1インターフェースへのアクセス
- Web UI: ブラウザでhttp://localhost:1420にアクセス
- ログ: ターミナルで直接アプリケーションログを確認し、バックエンドサービスと個々のエージェントの詳細な実行時情報を取得
次のステップ
アプリケーションが起動したら、WebインターフェースでValueCellの機能を操作して探索できます。
設定
詳細な設定情報については、CONFIGURATION_GUIDEを参照してください
ロードマップ
🤖 強化されたエージェント機能
取引能力
- 暗号通貨: OKX、BinanceとHyperliquid の取引所に対応、今後さらに多くの取引所を順次追加予定です…
- 証券: AI証券取引を段階的にサポート
市場拡大
- ヨーロッパ市場: FTSE、DAX、CAC 40などのヨーロッパ取引所のサポートを追加
- アジア市場: 日経、新興アジア市場へのカバレッジ拡大
- 商品市場: 石油、金、銀、農産物の分析
- 外国為替市場: 主要通貨ペアとクロスカレンシー分析
資産の多様化
- 債券: 国債、社債、利回り分析エージェント
- デリバティブ: オプション、先物、複雑な金融商品
- オルタナティブ投資: プライベートエクイティ、ヘッジファンド、ベンチャーキャピタル分析
高度な通知とプッシュタイプ
- リアルタイムアラート: 価格変動、出来高急増、テクニカルブレイクアウト
- スケジュールレポート: 日次/週次/月次ポートフォリオサマリー
- イベント駆動型通知: 決算発表、配当発表、規制変更
- カスタムトリガー: ユーザー定義の条件としきい値
- マルチチャネル配信: Discord と Webhook 統合
⚙️ 製品設定とパーソナライゼーション
マルチプラットフォーム製品
- デスクトップサポート: デスクトップとクライアント機能を段階的にサポート
- データベースホットアップデート: 互換性アップグレードの段階的サポート
国際化(i18n)
- 多言語サポート: 英語、中国語(簡体字/繁体字)、日本語、韓国語、スペイン語、フランス語
- ローカライズされた市場データ: 地域固有の金融用語とフォーマット
- 文化的適応: タイムゾーン、日付フォーマット、通貨設定
- エージェントのパーソナリティのローカライゼーション: 文化的に適切なコミュニケーションスタイル
トークンと認証管理
- APIキー管理: サードパーティAPIキーの安全な保存とローテーション
- OAuth統合: 主要な金融データプロバイダーのサポート
ユーザー設定とカスタマイズ
- 投資プロファイル: リスク許容度、投資期間、戦略の好み
- UI/UXカスタマイズ: ダーク/ライトモード、ダッシュボードレイアウト、ウィジェット設定
- エージェントの動作: コミュニケーション頻度、分析深度、レポートスタイル
- ポートフォリオ管理: カスタムベンチマーク、パフォーマンス指標、配分目標
メモリと学習システム
- 会話履歴: セッション間での永続的なチャット履歴
- ユーザー学習: ユーザー行動に基づく適応的な推奨
- 市場メモリ: 履歴コンテキストとパターン認識
- 設定の進化: 時間経過に伴う推奨の動的調整
🔧 ValueCell SDK開発
コアSDK機能
- Python SDK: エージェント統合とカスタマイズのための包括的なライブラリ
- WebSocketサポート: リアルタイムデータストリーミングと双方向通信
エージェント統合フレームワーク
- プラグインアーキテクチャ: サードパーティエージェントとツールの簡単な統合
- エージェントレジストリ: コミュニティ貢献エージェントのマーケットプレイス
開発者ツールとドキュメント
- インタラクティブAPIエクスプローラー: ライブテスト機能付きSwagger/OpenAPIドキュメント
- コード例: 複数のプログラミング言語でのサンプル実装
- テストフレームワーク: ユニットテスト、統合テスト、モックデータプロバイダー
ライセンス
本プロジェクトは Apache License 2.0 ライセンスの下で提供されています。詳細は LICENSE を参照してください。
📌 注意: Apache 2.0 は、ValueCell チームおよびコントリビューターが作成したオリジナルコードにのみ適用されます。サードパーティのコンポーネント(API、ウィジェット、ライブラリなど)は、それぞれのライセンスや利用規約に従います。
サードパーティコンポーネントとライセンス
ValueCell は外部サービスを統合し、サードパーティ製ウィジェットを埋め込みます。これらの利用は Apache 2.0 の対象外であり、その規約遵守はユーザー/開発者の責任です。
| コンポーネント | タイプ | ライセンス / 利用規約 |
|---|---|---|
| TradingView Advanced Chart | 埋め込み iframe ウィジェット | Free Advanced Charts Agreement(プロプライエタリ) |
| 取引所 API(Binance、OKX、Hyperliquid など) | REST/WebSocket エンドポイント | 各取引所の利用規約(例: Binance API 規約) |
| LLM プロバイダー(OpenAI、Azure、Google、DeepSeek など) | 推論 API | プロバイダー固有の利用規約(例: OpenAI 利用規約) |
Star History
File: README.zh.md
ValueCell
产品已上线 🔥🔥🔥
ValueCell 现已提供 A 股深度研究与市场分析,且无需部署——直接访问 valuecell.ai。
简介
ValueCell 是一个社区驱动的多智能体金融应用平台,我们的使命是打造世界最大的去中心化金融智能体社区。
它为您提供顶级的投资智能体团队,帮助您完成选股、调研、跟踪,甚至交易。
系统会将您的敏感信息完全托管在本地,确保核心数据安全。
欢迎大家加入 Discord 社区反馈使用中遇到的问题,并邀请更多开发者参与共建 🔥🔥🔥
注意:ValueCell团队人员不会主动私信社区参与者,项目仅为技术交流使用,投资有风险。⚠️
产品截图
核心特性
多智能体系统
- DeepResearch Agent: 获取并分析股票的基本面文件,输出准确的数据、可解释性的总结
- Strategy Agent: 支持多种加密资产、多策略智能交易,自动执行你的策略
- News Retrieval Agent: 支持个性化定时任务的新闻推送,及时跟踪关键信息
- 其他智能体:更多智能体正在规划中...
灵活集成
- 多种大语言模型提供商:支持 OpenRouter、SiliconFlow、Azure、Openai-compatible、Google、OpenAI和DeepSeek
- 热门市场数据:覆盖美国市场、加密货币市场、香港市场、中国市场等
- 多智能体框架兼容:通过 A2A 协议,支持 Langchain、Agno 等主流Agent框架,进行研发集成
- 交易所连接:支持实时路由至 OKX 和 Binance,并内置安全防护机制
快速开始
新用户
要快速开始,请从 GitHub 的发布页面下载 MacOS 或 Windows 的最新 ValueCell 应用程序。
安装后,初次使用 ValueCell 前请配置您首选的模型提供商。请参考应用程序内的说明或文档。
实时交易
- 配置 AI 模型: 通过网页UI界面添加你的 AI 模型 API Key。
- 配置交易所: 设置 Binance/HyperLiquid/OKX/Coinbase... API 凭证
- 创建策略: 将 AI 模型与交易所组合,创建自定义交易策略
- 监控与控制: 实时启动/停止策略,并实时监控交易表现
- 注意:当前仅支持合约交易(现货以1X合约实现),所以请确保合约账户存在余额
支持的交易所
| 交易所 | 说明 | 状态 |
|---|---|---|
| Binance | 仅支持国际站 binance.com,不支持美国站。使用 USDT-M 合约(USDT 本位合约)。请确保您的合约账户有足够的 USDT 余额。交易对格式:BTC/USDT。 Note:确保永续合约账户不为0。 申请API添加IP白名单通过搜索引擎搜索My IP查看 |
✅ 已测试 |
| Hyperliquid | 仅支持 USDC 作为保证金货币。使用您的主钱包地址 + API 钱包私钥认证(使用 API 页面 申请)。市价单会自动转换为 IoC 限价单。交易对格式必须手动调整为 SYMBOL/USDC(例如 WIF/USDC) 配置地址为主钱包地址+API钱包私钥 每次交易至少10U |
✅ 已测试 |
| OKX | 需要 API Key、Secret 和 Passphrase(OKX账号密码) 进行认证。支持 USDT 本位合约。交易对格式:BTC/USDT。 |
✅ 已测试 |
| Coinbase | 支持 USDT 本位合约。Coinbase International 尚未支持 | 🟡 部分测试 |
| Gate.io | 支持 USDT 本位合约。需要 API Key 和 Secret | 🟡 部分测试 |
| MEXC | 支持 USDT 本位合约。需要 API Key 和 Secret | 🟡 部分测试 |
| Blockchain | 支持 USDT 本位合约。需要 API Key 和 Secret | 🟡 部分测试 |
图例:
- ✅ 已测试: 在生产环境中经过充分测试和验证
- 🟡 部分测试: 代码实现已完成但未完全测试,可能需要调试
- 推荐: 优先使用经过充分测试的交易所(Binance, Hyperliquid, OKX)
注意事项
- 目前仅支持杠杆/合约交易,因此您需要确保您的永续合约(Perps)账户有足够的余额。
- 您必须妥善保管您的 API 密钥以避免资金损失。该应用程序将密钥本地存储在您的设备上,不会通过互联网发送给任何第三方。
- 为了确保您的账户安全,您需要定期重置您的 API 密钥。
注意:运行应用程序前,请确保所有前提条件已安装且环境变量已正确配置
如长时间没有更新,可以删除本地数据并重新启动:
- LanceDB 目录(位于系统应用目录,与
.env同路径):- macOS:
~/Library/Application Support/ValueCell/lancedb - Linux:
~/.config/valuecell/lancedb - Windows:
%APPDATA%\\ValueCell\\lancedb
- macOS:
- 知识目录(位于系统应用目录,与
.env同路径):- macOS:
~/Library/Application Support/ValueCell/.knowledge - Linux:
~/.config/valuecell/.knowledge - Windows:
%APPDATA%\\ValueCell\\.knowledge
- macOS:
- SQLite 数据库文件(位于系统应用目录,与
.env同路径):- macOS:
~/Library/Application Support/ValueCell/valuecell.db - Linux:
~/.config/valuecell/valuecell.db - Windows:
%APPDATA%\\ValueCell\\valuecell.db
- macOS:
开发者
诚挚邀请每位开发者加入Discord讨论组,我们会定期交流社区RoadMap以及未来社区贡献者权益规划
开发流程及标准详见:CONTRIBUTING.md
ValueCell 是一个基于Python的应用程序,且有完备的前端操作页面,支持多端应用。可以参考下面配置快速运行。
克隆仓库
git clone https://github.com/ValueCell-ai/valuecell.git
cd valuecell运行应用程序
启动完整的应用程序(前端、后端和智能体):
Linux / Macos
bash start.shWindows (PowerShell)
.\start.ps1访问界面
- Web UI:在浏览器中导航到 http://localhost:1420
- 日志:在终端就可以查看应用程序日志,获取后端服务和各个智能体的详细运行时信息
下一步
应用运行后,你可以通过网页界面探索并使用 ValueCell 的各项功能和能力。
配置
更多系统配置详情说明可以参考CONFIGURATION_GUIDE
Roadmap
🤖 增强智能体能力
交易能力
- 加密货币:支持okx、binance、Hyperliquid交易所,更多交易所规划接入中...
- 证券:逐步支持AI证券交易
市场扩展
- 欧洲市场:增加对富时指数、DAX、CAC 40和其他欧洲交易所的支持
- 亚洲市场:扩展对日经指数和新兴亚洲市场的覆盖
- 大宗商品市场:石油、黄金、白银、农产品分析
- 外汇市场:主要货币对和交叉货币分析
资产类别多样化
- 固定收益:政府债券、企业债券和收益率分析智能体
- 衍生品:期权、期货和复杂金融工具
- 另类投资:私募股权、对冲基金和风险投资分析
高级通知和推送类型
- 实时警报:价格变动、成交量激增和技术突破
- 定期报告:每日/每周/每月投资组合摘要
- 事件驱动通知:财报发布、股息公告、监管变化
- 自定义触发器:用户定义的条件和阈值
- 多渠道推送:Discord和webhook集成
⚙️ 产品配置与个性化
多端产品化
-- 客户端支持:逐步支持桌面端、客户端能力
-- 数据库热更新:逐步支持兼容性升级
国际化 (i18n)
- 多语言支持:英语、中文(简体/繁体)、日语、韩语、西班牙语、法语
- 本地化市场数据:特定地区的金融术语和格式
- 文化适应:时区、日期格式和货币偏好
- 智能体个性本地化:文化适宜的沟通风格
令牌和身份验证管理
- API密钥管理:第三方API密钥的安全存储和轮换
- OAuth集成:支持主要金融数据提供商
用户偏好和自定义
- 投资档案:风险承受能力、投资期限和策略偏好
- UI/UX自定义:深色/浅色模式、仪表板布局和小部件偏好
- 智能体行为:沟通频率、分析深度和报告风格
- 投资组合管理:自定义基准、绩效指标和配置目标
记忆和学习系统
- 对话历史:跨会话的持久聊天历史
- 用户学习:基于用户行为的自适应推荐
- 市场记忆:历史背景和模式识别
- 偏好演进:推荐的动态调整
🔧 ValueCell SDK开发
核心SDK功能
- Python SDK:用于智能体集成和自定义的核心代码,衔接前后端
- WebSocket支持:实时数据流和双向通信
智能体集成框架
- 插件架构:轻松集成第三方智能体和工具
- 智能体注册表:社区贡献智能体的市场
开发者工具和文档
- 交互式API浏览器:带有实时测试的Swagger/OpenAPI文档
- 代码示例:多种编程语言的示例实现
- 测试框架:单元测试、集成测试和模拟数据提供商
许可证
本项目依据 Apache License 2.0 授权发布;详情参见 LICENSE 文件。
📌 注意:Apache 2.0 仅适用于由 ValueCell 团队及贡献者创作的原始代码。第三方组件(如 API、挂件、库)受其各自的许可证与使用条款约束——见下方说明。
第三方组件与许可
ValueCell 集成外部服务并嵌入第三方挂件。其使用不受 Apache 2.0 覆盖,遵循其服务条款的合规责任由用户/开发者自行承担。
| 组件 | 类型 | 许可证 / 条款 |
|---|---|---|
| TradingView Advanced Chart | 嵌入式 iframe 挂件 | Free Advanced Charts Agreement(专有) |
| 交易所 API(Binance、OKX、Hyperliquid 等) | REST/WebSocket 接口 | 各交易所的服务条款(例如 Binance API 条款) |
| 大语言模型提供商(OpenAI、Azure、Google、DeepSeek 等) | 推理 API | 供应商特定的使用条款(例如 OpenAI 使用条款) |