From 64391e7cada6dbe8eb715794b8040fafa1238912 Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:04:42 +0800 Subject: [PATCH 1/2] fix : fix create strategy response --- .../server/api/routers/strategy_agent.py | 25 ++++++++++--------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/python/valuecell/server/api/routers/strategy_agent.py b/python/valuecell/server/api/routers/strategy_agent.py index 17f622c34..12daf69f0 100644 --- a/python/valuecell/server/api/routers/strategy_agent.py +++ b/python/valuecell/server/api/routers/strategy_agent.py @@ -19,7 +19,7 @@ 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 @@ -191,7 +191,10 @@ async def create_strategy_agent( # Do not fail the API due to persistence error pass - return status_content + # Unified success response with strategy_id + return SuccessResponse.create( + data={"strategy_id": status_content.strategy_id} + ) # If no status event received, fallback to DB-only creation fallback_strategy_id = generate_uuid("strategy") @@ -227,8 +230,9 @@ async def create_strategy_agent( except Exception: pass - return StrategyStatusContent( - strategy_id=fallback_strategy_id, status="stopped" + # Unified success response in fallback creation + return SuccessResponse.create( + data={"strategy_id": fallback_strategy_id}, msg="success" ) except Exception as exc: # Orchestrator failed; fallback to direct DB creation @@ -264,8 +268,9 @@ async def create_strategy_agent( ) except Exception: pass - return StrategyStatusContent( - strategy_id=fallback_strategy_id, status="stopped" + # Unified error response for orchestrator failure + return ErrorResponse.create( + code=StatusCode.INTERNAL_ERROR, msg=str(exc) ) except Exception as e: @@ -308,13 +313,9 @@ async def create_strategy_agent( 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 ErrorResponse.create(code=StatusCode.INTERNAL_ERROR, msg=str(e)) - 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): From 1abf6043ca5c51a6dc7be3eb72558fcd758a1350 Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Wed, 3 Dec 2025 17:51:02 +0800 Subject: [PATCH 2/2] refine code --- .../server/api/routers/strategy_agent.py | 123 ++---------------- 1 file changed, 11 insertions(+), 112 deletions(-) diff --git a/python/valuecell/server/api/routers/strategy_agent.py b/python/valuecell/server/api/routers/strategy_agent.py index 12daf69f0..7452aa9f6 100644 --- a/python/valuecell/server/api/routers/strategy_agent.py +++ b/python/valuecell/server/api/routers/strategy_agent.py @@ -25,7 +25,7 @@ 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, @@ -196,125 +200,20 @@ async def create_strategy_agent( data={"strategy_id": status_content.strategy_id} ) - # 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 in fallback creation - return SuccessResponse.create( - data={"strategy_id": fallback_strategy_id}, msg="success" + # 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 - # Unified error response for orchestrator failure + # 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 ErrorResponse.create(code=StatusCode.INTERNAL_ERROR, msg=str(e)) - return ErrorResponse.create(code=StatusCode.INTERNAL_ERROR, msg=str(e)) @router.post("/test-connection")