feat(agent): complete EvoAgent integration for all 6 agent roles
Migrate all agent roles from Legacy to EvoAgent architecture: - fundamentals_analyst, technical_analyst, sentiment_analyst, valuation_analyst - risk_manager, portfolio_manager Key changes: - EvoAgent now supports Portfolio Manager compatibility methods (_make_decision, get_decisions, get_portfolio_state, load_portfolio_state, update_portfolio) - Add UnifiedAgentFactory for centralized agent creation - ToolGuard with batch approval API and WebSocket broadcast - Legacy agents marked deprecated (AnalystAgent, RiskAgent, PMAgent) - Remove backend/agents/compat.py migration shim - Add run_id alongside workspace_id for semantic clarity - Complete integration test coverage (13 tests) - All smoke tests passing for 6 agent roles Constraint: Must maintain backward compatibility with existing run configs Constraint: Memory support must work with EvoAgent (no fallback to Legacy) Rejected: Separate PM implementation for EvoAgent | unified approach cleaner Confidence: high Scope-risk: broad Directive: EVO_AGENT_IDS env var still respected but defaults to all roles Not-tested: Kubernetes sandbox mode for skill execution
This commit is contained in:
@@ -4,6 +4,14 @@ This repository is in a split-first state: local development now assumes
|
||||
separate app surfaces and a dedicated WebSocket gateway instead of a single
|
||||
combined backend entrypoint.
|
||||
|
||||
For the canonical architecture summary, start with
|
||||
[docs/current-architecture.md](../docs/current-architecture.md). This file is
|
||||
service-focused and includes migration details.
|
||||
The matching visual diagram lives at
|
||||
[docs/current-architecture.excalidraw](../docs/current-architecture.excalidraw),
|
||||
and the next-step execution plan lives at
|
||||
[docs/development-roadmap.md](../docs/development-roadmap.md).
|
||||
|
||||
## Service Map
|
||||
|
||||
| Surface | Default port | Role |
|
||||
@@ -13,9 +21,32 @@ combined backend entrypoint.
|
||||
| `backend.apps.news_service` | `8002` | Read-only explain/news APIs such as story, similar days, range explain |
|
||||
| `backend.apps.runtime_service` | `8003` | Runtime lifecycle APIs under `/api/runtime/*` |
|
||||
| `backend.apps.openclaw_service` | `8004` | Read-only OpenClaw REST facade |
|
||||
| Gateway (`backend.main`) | `8765` | WebSocket feed, runtime event stream, legacy/compat orchestration path |
|
||||
| Gateway (`backend.main`) | `8765` | WebSocket feed, runtime event stream, pipeline execution |
|
||||
| OpenClaw Gateway | `18789` | External OpenClaw WebSocket endpoint consumed by 大时代 gateway |
|
||||
|
||||
## Runtime Modes
|
||||
|
||||
### Standalone Mode (Direct Gateway Startup)
|
||||
|
||||
For simple deployments or backward compatibility:
|
||||
|
||||
```bash
|
||||
python -m backend.main --mode live --host 0.0.0.0 --port 8765
|
||||
```
|
||||
|
||||
In this mode, Gateway runs as the primary process with all components
|
||||
(Pipeline, Market Service, Scheduler) loaded in-process.
|
||||
|
||||
### Microservice Mode (Recommended)
|
||||
|
||||
For development and production with service isolation:
|
||||
|
||||
```bash
|
||||
./start-dev.sh
|
||||
```
|
||||
|
||||
This starts all services with `runtime_service` managing the Gateway lifecycle.
|
||||
|
||||
## What Runs By Default In Dev
|
||||
|
||||
The supported local dev path is:
|
||||
@@ -30,7 +61,7 @@ That script starts:
|
||||
- `trading_service` on `8001`
|
||||
- `news_service` on `8002`
|
||||
- `runtime_service` on `8003`
|
||||
- 大时代 gateway on `8765`
|
||||
- 大时代 gateway on `8765` (as subprocess of runtime_service)
|
||||
|
||||
It does **not** start `openclaw_service` on `8004`.
|
||||
|
||||
@@ -47,7 +78,21 @@ python -m uvicorn backend.apps.agent_service:app --host 0.0.0.0 --port 8000 --re
|
||||
python -m uvicorn backend.apps.trading_service:app --host 0.0.0.0 --port 8001 --reload
|
||||
python -m uvicorn backend.apps.news_service:app --host 0.0.0.0 --port 8002 --reload
|
||||
python -m uvicorn backend.apps.runtime_service:app --host 0.0.0.0 --port 8003 --reload
|
||||
python -m backend.main --mode live --host 0.0.0.0 --port 8765
|
||||
```
|
||||
|
||||
The Gateway is started by `runtime_service` via the `/api/runtime/start` API,
|
||||
not manually. To start a runtime:
|
||||
|
||||
```bash
|
||||
curl -X POST http://localhost:8003/api/runtime/start \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"launch_mode": "fresh",
|
||||
"tickers": ["AAPL", "MSFT"],
|
||||
"schedule_mode": "daily",
|
||||
"trigger_time": "09:30",
|
||||
"initial_cash": 100000
|
||||
}'
|
||||
```
|
||||
|
||||
Optional OpenClaw REST surface:
|
||||
@@ -60,13 +105,72 @@ python -m uvicorn backend.apps.openclaw_service:app --host 0.0.0.0 --port 8004 -
|
||||
|
||||
The runtime path is intentionally split:
|
||||
|
||||
- `runtime_service` handles start, stop, restart, current runtime info, logs, and runtime state APIs
|
||||
### Control Plane (runtime_service :8003)
|
||||
|
||||
- **Gateway lifecycle**: Start, stop, restart Gateway processes
|
||||
- **Configuration**: Bootstrap values, runtime parameters
|
||||
- **Health monitoring**: Gateway process status, port management
|
||||
- **Run history**: List historical runs, restore from snapshots
|
||||
|
||||
### Data Plane (Gateway :8765)
|
||||
|
||||
- **WebSocket transport**: Live event streaming to frontend
|
||||
- **Pipeline execution**: Analysis -> Communication -> Decision -> Execution
|
||||
- **Market data**: Real-time price feeds and backtest simulation
|
||||
- **Scheduler**: Trading cycle orchestration
|
||||
|
||||
### Supporting Services
|
||||
|
||||
- `agent_service` handles control-plane reads and writes for agents, workspaces, files, and approvals
|
||||
- `backend.main` / gateway hosts the live WebSocket channel and coordinates market service, scheduler, and pipeline execution
|
||||
- `trading_service` provides read-only trading data
|
||||
- `news_service` provides news enrichment and explanation APIs
|
||||
|
||||
The practical request path looks like:
|
||||
|
||||
`frontend -> runtime_service/control APIs -> gateway/runtime manager -> market service + pipeline + storage`
|
||||
```
|
||||
frontend -> runtime_service/control APIs -> gateway/runtime manager -> market service + pipeline + storage
|
||||
```
|
||||
|
||||
## runtime_service as Gateway Process Manager
|
||||
|
||||
The `runtime_service` is the **Gateway Process Manager** in the microservice
|
||||
architecture. Its responsibilities:
|
||||
|
||||
1. **Process Management**
|
||||
- Spawns Gateway as subprocess via `_start_gateway_process()`
|
||||
- Monitors process health via `gateway_process.poll()`
|
||||
- Handles graceful shutdown (SIGTERM) and force kill
|
||||
|
||||
2. **Port Management**
|
||||
- Finds available ports (`_find_available_port()`)
|
||||
- Tracks current Gateway port in RuntimeState
|
||||
|
||||
3. **Lifecycle APIs**
|
||||
- `POST /api/runtime/start` - Create run, spawn Gateway
|
||||
- `POST /api/runtime/stop` - Stop Gateway process
|
||||
- `POST /api/runtime/restart` - Stop then start new runtime
|
||||
- `GET /api/runtime/gateway/status` - Check Gateway health
|
||||
|
||||
4. **State Management**
|
||||
- Maintains RuntimeState singleton (thread-safe)
|
||||
- Tracks runtime_manager reference for in-memory state
|
||||
- Falls back to persisted snapshots when Gateway is stopped
|
||||
|
||||
### Gateway Subprocess Architecture
|
||||
|
||||
```
|
||||
runtime_service (:8003)
|
||||
|
|
||||
|-- spawns --> Gateway subprocess (:8765)
|
||||
|
|
||||
|-- TradingPipeline
|
||||
|-- MarketService
|
||||
|-- Scheduler
|
||||
|-- WebSocket server
|
||||
```
|
||||
|
||||
The Gateway subprocess runs `backend.gateway_server` module (not `backend.main`)
|
||||
with run-specific configuration passed via CLI arguments.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
@@ -144,7 +248,7 @@ backend.apps.agent_service
|
||||
└─ control-plane routes
|
||||
|
||||
backend.apps.runtime_service
|
||||
└─ runtime lifecycle routes
|
||||
└─ runtime lifecycle routes, Gateway process management
|
||||
|
||||
backend.apps.trading_service
|
||||
└─ read-only trading contract
|
||||
@@ -155,6 +259,40 @@ backend.apps.news_service
|
||||
backend.apps.openclaw_service
|
||||
└─ optional OpenClaw REST facade
|
||||
|
||||
backend.main / backend.services.gateway
|
||||
└─ live orchestration, feed transport, scheduler, runtime coordination
|
||||
backend.gateway_server
|
||||
└─ Gateway subprocess entry point (run-scoped)
|
||||
|
||||
backend.main
|
||||
└─ standalone Gateway entry point (compatibility)
|
||||
```
|
||||
|
||||
## Migration Boundaries
|
||||
|
||||
Some agent-migration helpers still exist in the tree, but they are not part of
|
||||
the supported runtime path yet:
|
||||
|
||||
No workspace-loading helper remains on `TradingPipeline`. Runtime agent loading
|
||||
is expected to stay on the run-scoped creation path.
|
||||
|
||||
Also note the remaining naming split:
|
||||
|
||||
- `workspaces/` = design-time CRUD registry
|
||||
- `runs/<run_id>/` = runtime state and run-scoped agent assets
|
||||
|
||||
## Future Architecture Direction
|
||||
|
||||
### Current State
|
||||
|
||||
- Pipeline logic lives in Gateway process
|
||||
- Gateway is spawned as subprocess by runtime_service
|
||||
- Standalone mode (`backend.main`) preserved for compatibility
|
||||
|
||||
### Target State
|
||||
|
||||
- Pipeline stages become independent services
|
||||
- Gateway becomes thin event router
|
||||
- runtime_service becomes full orchestrator
|
||||
- Standalone mode deprecated and removed
|
||||
|
||||
See [docs/development-roadmap.md](../docs/development-roadmap.md) for detailed
|
||||
phase planning.
|
||||
|
||||
Reference in New Issue
Block a user