From d81464b869a422599fa4585f107d4c3612ea24b4 Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Thu, 9 Apr 2026 07:31:09 +0000 Subject: [PATCH] fix: flatten strategy config schema to match engine expectations LLM was outputting nested params structure but engines expect flat fields. This caused backtesting and simulation to never trigger any trades. Changes: - llm_connector.py: Update prompt to output flat condition structure - crew.py: Update StrategyValidator to validate flat structure - crew.py: Update StrategyExplainer to read flat structure Fixes #25 --- src/backend/app/services/ai_agent/crew.py | 40 ++++++++----------- .../app/services/ai_agent/llm_connector.py | 21 +++++----- 2 files changed, 27 insertions(+), 34 deletions(-) diff --git a/src/backend/app/services/ai_agent/crew.py b/src/backend/app/services/ai_agent/crew.py index 40ac0e9..2cf3533 100644 --- a/src/backend/app/services/ai_agent/crew.py +++ b/src/backend/app/services/ai_agent/crew.py @@ -33,29 +33,24 @@ class StrategyValidator: errors.append(f"Condition {i}: unsupported type '{cond_type}'") continue - params = condition.get("params", {}) if cond_type in ["price_drop", "price_rise", "volume_spike"]: - if "token" not in params: + if "token" not in condition: errors.append(f"Condition {i}: missing 'token'") - if "threshold_percent" not in params: - errors.append(f"Condition {i}: missing 'threshold_percent'") - elif not isinstance(params["threshold_percent"], (int, float)): - errors.append( - f"Condition {i}: 'threshold_percent' must be a number" - ) - elif params["threshold_percent"] <= 0: - errors.append( - f"Condition {i}: 'threshold_percent' must be positive" - ) + if "threshold" not in condition: + errors.append(f"Condition {i}: missing 'threshold'") + elif not isinstance(condition["threshold"], (int, float)): + errors.append(f"Condition {i}: 'threshold' must be a number") + elif condition["threshold"] <= 0: + errors.append(f"Condition {i}: 'threshold' must be positive") elif cond_type == "price_level": - if "token" not in params: + if "token" not in condition: errors.append(f"Condition {i}: missing 'token'") - if "price" not in params: + if "price" not in condition: errors.append(f"Condition {i}: missing 'price'") - if "direction" not in params: + if "direction" not in condition: errors.append(f"Condition {i}: missing 'direction'") - elif params["direction"] not in ["above", "below"]: + elif condition["direction"] not in ["above", "below"]: errors.append( f"Condition {i}: direction must be 'above' or 'below'" ) @@ -85,23 +80,22 @@ class StrategyExplainer: explanations.append("This strategy will trigger when:") for cond in cond_list: cond_type = cond.get("type") - params = cond.get("params", {}) - token = params.get("token", "the token") + token = cond.get("token", "the token") if cond_type == "price_drop": - pct = params.get("threshold_percent", 0) + pct = cond.get("threshold", 0) explanations.append(f" - {token} price drops by {pct}%") elif cond_type == "price_rise": - pct = params.get("threshold_percent", 0) + pct = cond.get("threshold", 0) explanations.append(f" - {token} price rises by {pct}%") elif cond_type == "volume_spike": - pct = params.get("threshold_percent", 0) + pct = cond.get("threshold", 0) explanations.append( f" - {token} trading volume increases by {pct}%" ) elif cond_type == "price_level": - price = params.get("price", 0) - direction = params.get("direction", "unknown") + price = cond.get("price", 0) + direction = cond.get("direction", "unknown") explanations.append( f" - {token} price crosses {direction} ${price}" ) diff --git a/src/backend/app/services/ai_agent/llm_connector.py b/src/backend/app/services/ai_agent/llm_connector.py index 5b8f726..dd129da 100644 --- a/src/backend/app/services/ai_agent/llm_connector.py +++ b/src/backend/app/services/ai_agent/llm_connector.py @@ -61,9 +61,9 @@ class MiniMaxConnector: system_prompt = """You are a trading strategy designer. Parse the user's natural language request into a JSON strategy_config object. Supported conditions (MVP): -- price_drop: Token price drops by X% (requires: token, threshold_percent) -- price_rise: Token price rises by X% (requires: token, threshold_percent) -- volume_spike: Trading volume increases X% (requires: token, threshold_percent) +- price_drop: Token price drops by X% (requires: token, threshold) +- price_rise: Token price rises by X% (requires: token, threshold) +- volume_spike: Trading volume increases X% (requires: token, threshold) - price_level: Price crosses above/below X (requires: token, price, direction) Output ONLY valid JSON with this schema: @@ -71,18 +71,17 @@ Output ONLY valid JSON with this schema: "conditions": [ { "type": "price_drop|price_rise|volume_spike|price_level", - "params": { - "token": "TOKEN_SYMBOL", - "threshold_percent": number, // for price_drop, price_rise, volume_spike - "price": number, // for price_level - "direction": "above|below" // for price_level - } + "token": "TOKEN_SYMBOL", + "chain": "bsc", + "threshold": number, // for price_drop, price_rise, volume_spike + "price": number, // for price_level + "direction": "above|below", // for price_level + "timeframe": "1h" } ], "actions": [ { - "type": "buy|sell|notify", - "params": {} + "type": "buy|sell|notify" } ] }