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:
261
docs/legacy-inventory.md
Normal file
261
docs/legacy-inventory.md
Normal file
@@ -0,0 +1,261 @@
|
||||
# Legacy Inventory
|
||||
|
||||
This file records the major legacy or compatibility-oriented surfaces that still
|
||||
exist in the repository.
|
||||
|
||||
It is not a deletion plan by itself. Its purpose is to separate:
|
||||
|
||||
- current source-of-truth runtime paths
|
||||
- intentional compatibility surfaces
|
||||
- historical directories and scripts that should not guide new development
|
||||
|
||||
## Source Of Truth
|
||||
|
||||
These are the current defaults to build against:
|
||||
|
||||
- `runs/<run_id>/`
|
||||
- runtime state, bootstrap configuration, agent runtime assets, logs
|
||||
- split services
|
||||
- `backend.apps.agent_service` on `:8000`
|
||||
- `backend.apps.runtime_service` on `:8003`
|
||||
- `backend.apps.trading_service` on `:8001`
|
||||
- `backend.apps.news_service` on `:8002`
|
||||
- gateway process
|
||||
- `backend.main`
|
||||
- `backend.services.gateway` on `:8765`
|
||||
|
||||
## Compatibility Surface Classification
|
||||
|
||||
All compatibility surfaces are categorized into three buckets:
|
||||
|
||||
### 1. Stable and Intentional (Keep)
|
||||
|
||||
These have clear operational reasons to exist and are documented as intentional
|
||||
compatibility surfaces with explicit ownership.
|
||||
|
||||
| Surface | Location | Owner | Reason |
|
||||
|---------|----------|-------|--------|
|
||||
| Gateway-first production | `scripts/run_prod.sh`, `deploy/systemd/`, `deploy/nginx/` | ops-team | Current production example runs gateway directly and proxies `/ws` |
|
||||
| Dashboard export layer | `runs/<run_id>/team_dashboard/*.json` | frontend-team | Downstream dashboard consumers read these exports |
|
||||
| Design-time workspace registry | `workspaces/`, `backend.api.workspaces` | control-plane-team | Control-plane editing and registry-style management |
|
||||
| Gateway WebSocket transport | `backend.services.gateway` on `:8765` | runtime-team | Live event streaming contract for frontend |
|
||||
|
||||
**Status**: These are NOT migration leftovers. Do not remove without explicit
|
||||
replacement plan signed off by owning team.
|
||||
|
||||
### 2. Temporary and Shrinking (Mark for Removal)
|
||||
|
||||
These should not grow further. Keep only until concrete replacement is fully
|
||||
in use.
|
||||
|
||||
| Surface | Location | Replacement | ETA |
|
||||
|---------|----------|-------------|-----|
|
||||
| Legacy analyst agents | `backend.agents.analyst.*` | `EvoAgent` | After EvoAgent smoke tests pass |
|
||||
| Mixed workspace_id semantics | `/api/workspaces/{id}/agents/...` | Explicit `run_id` vs `workspace_id` routes | TBD |
|
||||
| Root-level runtime directories | `live/`, `backtest/`, `production/` | `runs/<run_id>/` | Already deprecated, safe to ignore |
|
||||
|
||||
**Status**: Do not add new code using these surfaces. Migrate existing usage
|
||||
when touching related code.
|
||||
|
||||
### 3. Deferred Until Topology Final (Revisit Later)
|
||||
|
||||
These are real migration boundaries, but removing them prematurely would create
|
||||
churn without simplifying the current runtime. Revisit only after production
|
||||
topology and service-routing policy are frozen.
|
||||
|
||||
| Surface | Current State | Decision Needed |
|
||||
|---------|---------------|-----------------|
|
||||
| OpenClaw dual integration | REST facade (`:8004`) + Gateway WebSocket (`:18789`) | Which surface is the long-term contract? |
|
||||
| Env-dependent service fallbacks | `TRADING_SERVICE_URL`, `NEWS_SERVICE_URL` fallbacks to local modules | Remove fallbacks and require explicit URLs? |
|
||||
| Split-service production deploy | Docs show gateway-first, dev uses split-service | Align production with dev topology? |
|
||||
|
||||
**Status**: Document current behavior. Do not actively remove until topology
|
||||
decisions are finalized.
|
||||
|
||||
## Detailed Surface Documentation
|
||||
|
||||
### Gateway-First Production Example
|
||||
|
||||
**Files**:
|
||||
- `scripts/run_prod.sh` - Production launch script
|
||||
- `deploy/systemd/evotraders.service` - systemd unit
|
||||
- `deploy/nginx/bigtime.cillinn.com.conf` - HTTPS + WebSocket proxy
|
||||
- `deploy/nginx/bigtime.cillinn.com.http.conf` - HTTP variant
|
||||
|
||||
**Behavior**:
|
||||
```bash
|
||||
# scripts/run_prod.sh launches:
|
||||
python3 -m backend.main \
|
||||
--mode live \
|
||||
--config-name production \
|
||||
--host 127.0.0.1 \
|
||||
--port 8765
|
||||
```
|
||||
|
||||
**nginx proxies**:
|
||||
- `/ws` -> `127.0.0.1:8765` (WebSocket upgrade)
|
||||
- `/` -> static files in `/var/www/bigtime/current`
|
||||
|
||||
**Why this exists**:
|
||||
- Simpler production deployment (single process + nginx)
|
||||
- WebSocket is the practical live event contract for frontend
|
||||
- Split-service topology adds operational complexity not needed for all deployments
|
||||
|
||||
**Ownership**: ops-team
|
||||
**Status**: Stable and intentional
|
||||
|
||||
### OpenClaw Dual Integration
|
||||
|
||||
Two different integration surfaces exist for OpenClaw:
|
||||
|
||||
#### A. REST Facade (Port 8004)
|
||||
|
||||
**File**: `backend/apps/openclaw_service.py`
|
||||
**Routes**: `backend/api/openclaw.py` (prefix `/api/openclaw`)
|
||||
|
||||
**Purpose**:
|
||||
- Read-only OpenClaw CLI integration
|
||||
- Typed Pydantic models for all responses
|
||||
- Direct HTTP/REST access to OpenClaw state
|
||||
|
||||
**Use when**:
|
||||
- You need typed, stable API contracts
|
||||
- You want to poll OpenClaw status from external systems
|
||||
- You need programmatic access without WebSocket complexity
|
||||
|
||||
**Example**:
|
||||
```bash
|
||||
curl http://localhost:8004/api/openclaw/status
|
||||
```
|
||||
|
||||
#### B. Gateway WebSocket Integration (Port 18789)
|
||||
|
||||
**Files**:
|
||||
- `backend/services/gateway_openclaw_handlers.py`
|
||||
- `shared/client/openclaw_websocket_client.py`
|
||||
|
||||
**Purpose**:
|
||||
- Real-time bidirectional communication with OpenClaw
|
||||
- Event streaming and live updates
|
||||
- Integration with Gateway event flow
|
||||
|
||||
**Use when**:
|
||||
- You need real-time updates
|
||||
- You're already connected to Gateway WebSocket
|
||||
- You want event-driven rather than polling architecture
|
||||
|
||||
**Example**:
|
||||
```javascript
|
||||
// Frontend connects to ws://localhost:18789
|
||||
const ws = new WebSocket('ws://localhost:18789');
|
||||
```
|
||||
|
||||
#### Key Differences
|
||||
|
||||
| Aspect | REST Facade (8004) | Gateway WebSocket (18789) |
|
||||
|--------|-------------------|---------------------------|
|
||||
| Protocol | HTTP/REST | WebSocket |
|
||||
| Access pattern | Request/response | Event-driven |
|
||||
| Typing | Pydantic models | JSON messages |
|
||||
| Real-time | Polling required | Push notifications |
|
||||
| Use case | External integrations, scripts | Frontend, live dashboards |
|
||||
| Stability | Higher (explicit contracts) | Evolving with Gateway |
|
||||
|
||||
**Decision needed**: Which surface becomes the long-term contract?
|
||||
- REST facade is more stable but read-only
|
||||
- WebSocket integration is more capable but tied to Gateway evolution
|
||||
|
||||
**Ownership**: runtime-team
|
||||
**Status**: Deferred until topology final
|
||||
|
||||
### Dashboard Export Layer
|
||||
|
||||
**Files**: `runs/<run_id>/team_dashboard/*.json`
|
||||
|
||||
**Purpose**:
|
||||
- Compatibility/export layer for dashboard consumers
|
||||
- Non-authoritative snapshot of runtime state
|
||||
- Can be disabled via `ENABLE_DASHBOARD_COMPAT_EXPORTS=false`
|
||||
|
||||
**Why not remove**:
|
||||
- Downstream consumers still read these files
|
||||
- Provides decoupling between runtime and dashboard
|
||||
|
||||
**Ownership**: frontend-team
|
||||
**Status**: Stable and intentional
|
||||
|
||||
### Design-Time Workspace Registry
|
||||
|
||||
**Files**:
|
||||
- `workspaces/` directory
|
||||
- `backend/api/workspaces.py`
|
||||
- `backend/agents/workspace_manager.py`
|
||||
|
||||
**Purpose**:
|
||||
- Control-plane editing and registry-style management
|
||||
- Design-time CRUD for agent workspaces
|
||||
- Separate from runtime state in `runs/<run_id>/`
|
||||
|
||||
**Key distinction**:
|
||||
- `workspaces/` = design-time registry (what agents *could* be)
|
||||
- `runs/<run_id>/` = runtime state (what agents *are* right now)
|
||||
|
||||
**Ownership**: control-plane-team
|
||||
**Status**: Stable and intentional
|
||||
|
||||
## Historical Or High-Risk-To-Misread Surfaces
|
||||
|
||||
These remain in the tree, but they should not define the architecture for new work.
|
||||
|
||||
### Root-level runtime directories
|
||||
|
||||
- `live/`
|
||||
- `backtest/`
|
||||
- `production/`
|
||||
|
||||
**Read**:
|
||||
|
||||
- treat these as historical or compatibility-oriented data/layout artifacts
|
||||
- do not use them as the default runtime contract for new features
|
||||
|
||||
### Mixed `workspace_id` semantics on agent routes
|
||||
|
||||
- `/api/workspaces/{workspace_id}/agents/...`
|
||||
|
||||
**Read**:
|
||||
|
||||
- design-time CRUD routes use `workspace_id` as a registry workspace id
|
||||
- profile, skills, and editable file routes use `workspace_id` as a run id
|
||||
|
||||
**Mitigation already in repo**:
|
||||
|
||||
- `agent_service /api/status` exposes scope metadata
|
||||
- runtime-read responses expose `scope_type` and `scope_note`
|
||||
|
||||
### Partial EvoAgent rollout
|
||||
|
||||
- `EVO_AGENT_IDS`
|
||||
- staged smoke coverage in `scripts/smoke_evo_runtime.py`
|
||||
|
||||
**Read**:
|
||||
|
||||
- EvoAgent is still a controlled rollout path
|
||||
- legacy analyst/risk/PM implementations remain the default runtime path for now
|
||||
|
||||
## Recommended Usage
|
||||
|
||||
When in doubt:
|
||||
|
||||
1. trust `docs/current-architecture.md`
|
||||
2. trust `runs/<run_id>/` over root-level runtime directories
|
||||
3. treat `workspaces/` as control-plane registry, not runtime truth
|
||||
4. treat deploy artifacts as the current checked-in example, not the full system contract
|
||||
5. check this file's **Compatibility Surface Classification** before assuming something is legacy
|
||||
|
||||
## Change Log
|
||||
|
||||
| Date | Change |
|
||||
|------|--------|
|
||||
| 2026-03-31 | Added Compatibility Surface Classification (3 buckets) |
|
||||
| 2026-03-31 | Documented OpenClaw dual integration (REST vs WebSocket) |
|
||||
| 2026-03-31 | Added ownership and status to all surfaces |
|
||||
Reference in New Issue
Block a user