diff --git a/python/valuecell/server/api/routers/strategy_agent.py b/python/valuecell/server/api/routers/strategy_agent.py index 17f622c34..7452aa9f6 100644 --- a/python/valuecell/server/api/routers/strategy_agent.py +++ b/python/valuecell/server/api/routers/strategy_agent.py @@ -19,13 +19,13 @@ from valuecell.config.loader import get_config_loader from valuecell.core.coordinate.orchestrator import AgentOrchestrator from valuecell.core.types import CommonResponseEvent, UserInput, UserInputMetadata -from valuecell.server.api.schemas.base import SuccessResponse +from valuecell.server.api.schemas.base import ErrorResponse, StatusCode, SuccessResponse # Note: Strategy type is now part of TradingConfig in the request body. from valuecell.server.db.connection import get_db from valuecell.server.db.repositories import get_strategy_repository from valuecell.server.services.strategy_autoresume import auto_resume_strategies -from valuecell.utils.uuid import generate_conversation_id, generate_uuid +from valuecell.utils.uuid import generate_conversation_id def create_strategy_agent_router() -> APIRouter: @@ -178,6 +178,10 @@ async def create_strategy_agent( metadata["stop_reason_detail"] = ( status_content.stop_reason_detail ) + return ErrorResponse.create( + code=StatusCode.INTERNAL_ERROR, + msg=status_content.stop_reason_detail, + ) repo.upsert_strategy( strategy_id=status_content.strategy_id, name=name, @@ -191,130 +195,26 @@ async def create_strategy_agent( # Do not fail the API due to persistence error pass - return status_content - - # If no status event received, fallback to DB-only creation - fallback_strategy_id = generate_uuid("strategy") - try: - name = ( - request.trading_config.strategy_name - or f"Strategy-{fallback_strategy_id.split('-')[-1][:8]}" - ) - metadata = { - "agent_name": agent_name, - "strategy_type": strategy_type_enum, - "model_provider": request.llm_model_config.provider, - "model_id": request.llm_model_config.model_id, - "exchange_id": request.exchange_config.exchange_id, - "trading_mode": ( - request.exchange_config.trading_mode.value - if hasattr(request.exchange_config.trading_mode, "value") - else str(request.exchange_config.trading_mode) - ), - "fallback": True, - "stop_reason": "error", - "stop_reason_detail": "No status event from orchestrator", - } - repo.upsert_strategy( - strategy_id=fallback_strategy_id, - name=name, - description=None, - user_id=user_input_meta.user_id, - status="stopped", - config=request.model_dump(), - metadata=metadata, - ) - except Exception: - pass + # Unified success response with strategy_id + return SuccessResponse.create( + data={"strategy_id": status_content.strategy_id} + ) - return StrategyStatusContent( - strategy_id=fallback_strategy_id, status="stopped" + # No status event received; do NOT persist or fallback, return error only + return ErrorResponse.create( + code=StatusCode.INTERNAL_ERROR, + msg="No status event from orchestrator", ) except Exception as exc: - # Orchestrator failed; fallback to direct DB creation - fallback_strategy_id = generate_uuid("strategy") - try: - name = ( - request.trading_config.strategy_name - or f"Strategy-{fallback_strategy_id.split('-')[-1][:8]}" - ) - metadata = { - "agent_name": agent_name, - "strategy_type": strategy_type_enum, - "model_provider": request.llm_model_config.provider, - "model_id": request.llm_model_config.model_id, - "exchange_id": request.exchange_config.exchange_id, - "trading_mode": ( - request.exchange_config.trading_mode.value - if hasattr(request.exchange_config.trading_mode, "value") - else str(request.exchange_config.trading_mode) - ), - "fallback": True, - "stop_reason": "error", - "stop_reason_detail": str(exc), - } - repo.upsert_strategy( - strategy_id=fallback_strategy_id, - name=name, - description=None, - user_id=user_input_meta.user_id, - status="stopped", - config=request.model_dump(), - metadata=metadata, - ) - except Exception: - pass - return StrategyStatusContent( - strategy_id=fallback_strategy_id, status="stopped" + # Orchestrator failed; do NOT persist or fallback, return error only + return ErrorResponse.create( + code=StatusCode.INTERNAL_ERROR, msg=str(exc) ) except Exception as e: - # As a last resort, log the exception and attempt to create a DB record - # with "error" status, then return a structured error. + # As a last resort, log the exception and return error without persistence or fallback. logger.exception(f"Failed to create strategy in API endpoint: {e}") - fallback_strategy_id = generate_uuid("strategy") - try: - repo = get_strategy_repository(db_session=db) - name = ( - request.trading_config.strategy_name - or f"Strategy-{fallback_strategy_id.split('-')[-1][:8]}" - ) - metadata = { - "agent_name": agent_name, - "strategy_type": strategy_type_enum, - "model_provider": request.llm_model_config.provider, - "model_id": request.llm_model_config.model_id, - "exchange_id": request.exchange_config.exchange_id, - "trading_mode": ( - request.exchange_config.trading_mode.value - if hasattr(request.exchange_config.trading_mode, "value") - else str(request.exchange_config.trading_mode) - ), - "fallback": True, - "stop_reason": "error", - "stop_reason_detail": str(e), - } - repo.upsert_strategy( - strategy_id=fallback_strategy_id, - name=name, - description=f"Failed to create strategy: {str(e)}", - user_id="default_user", # Assuming a default user - status=StrategyStatus.ERROR.value, - config=request.model_dump(), - metadata=metadata, - ) - except Exception as db_exc: - logger.exception( - f"Failed to persist error state for strategy: {db_exc}" - ) - # If DB persistence also fails, return a generic error without a valid ID - return StrategyStatusContent( - strategy_id="unknown", status=StrategyStatus.ERROR - ) - - return StrategyStatusContent( - strategy_id=fallback_strategy_id, status=StrategyStatus.ERROR - ) + return ErrorResponse.create(code=StatusCode.INTERNAL_ERROR, msg=str(e)) @router.post("/test-connection") async def test_exchange_connection(request: ExchangeConfig):