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:
2026-04-02 00:55:08 +08:00
parent 0fa413380c
commit 16b54d5ccc
73 changed files with 9454 additions and 904 deletions

View File

@@ -22,16 +22,6 @@ from agentscope.message import TextBlock
from agentscope.tool import ToolResponse
from backend.data.provider_utils import normalize_symbol
from backend.skills.builtin.valuation_review.scripts.dcf_report import (
build_dcf_report,
)
from backend.skills.builtin.valuation_review.scripts.multiple_valuation_report import (
build_ev_ebitda_report,
build_residual_income_report,
)
from backend.skills.builtin.valuation_review.scripts.owner_earnings_report import (
build_owner_earnings_report,
)
from backend.tools.data_tools import (
get_company_news,
get_financial_metrics,
@@ -41,10 +31,12 @@ from backend.tools.data_tools import (
prices_to_df,
search_line_items,
)
from backend.tools.sandboxed_executor import get_sandbox
from backend.tools.technical_signals import StockTechnicalAnalyzer
logger = logging.getLogger(__name__)
_technical_analyzer = StockTechnicalAnalyzer()
_sandbox = get_sandbox()
def _to_text_response(text: str) -> ToolResponse:
@@ -869,7 +861,13 @@ def dcf_valuation_analysis(
},
)
return _to_text_response(build_dcf_report(rows, current_date))
return _to_text_response(
_sandbox.execute_skill(
skill_name="builtin/valuation_review",
function_name="build_dcf_report",
function_args={"rows": rows, "current_date": current_date},
)
)
@safe
@@ -958,7 +956,13 @@ def owner_earnings_valuation_analysis(
},
)
return _to_text_response(build_owner_earnings_report(rows, current_date))
return _to_text_response(
_sandbox.execute_skill(
skill_name="builtin/valuation_review",
function_name="build_owner_earnings_report",
function_args={"rows": rows, "current_date": current_date},
)
)
@safe
@@ -1033,7 +1037,13 @@ def ev_ebitda_valuation_analysis(
},
)
return _to_text_response(build_ev_ebitda_report(rows, current_date))
return _to_text_response(
_sandbox.execute_skill(
skill_name="builtin/valuation_review",
function_name="build_ev_ebitda_report",
function_args={"rows": rows, "current_date": current_date},
)
)
@safe
@@ -1114,7 +1124,13 @@ def residual_income_valuation_analysis(
},
)
return _to_text_response(build_residual_income_report(rows, current_date))
return _to_text_response(
_sandbox.execute_skill(
skill_name="builtin/valuation_review",
function_name="build_residual_income_report",
function_args={"rows": rows, "current_date": current_date},
)
)
# Tool Registry for dynamic toolkit creation