From 6f23b322d3b6fab94d9ab0c272ea75013f597e2e Mon Sep 17 00:00:00 2001 From: shokollm <270575765+shokollm@users.noreply.github.com> Date: Fri, 10 Apr 2026 12:14:32 +0000 Subject: [PATCH] feat: add token search in modal when confirming address --- src/backend/app/api/bots.py | 1 + src/backend/app/db/schemas.py | 1 + .../app/services/ai_agent/conversational.py | 34 +++++++- src/frontend/src/lib/api/types.ts | 8 ++ src/frontend/src/routes/bot/[id]/+page.svelte | 84 ++++++++++++++++++- 5 files changed, 125 insertions(+), 3 deletions(-) diff --git a/src/backend/app/api/bots.py b/src/backend/app/api/bots.py index 36d6ed9..051a628 100644 --- a/src/backend/app/api/bots.py +++ b/src/backend/app/api/bots.py @@ -225,6 +225,7 @@ def chat( success=result.get("success", False), strategy_needs_confirmation=result.get("strategy_needs_confirmation", False), strategy_data=result.get("strategy_data") if result.get("strategy_needs_confirmation") else None, + token_search_results=result.get("token_search_results"), ) diff --git a/src/backend/app/db/schemas.py b/src/backend/app/db/schemas.py index 467f95d..30d2a5f 100644 --- a/src/backend/app/db/schemas.py +++ b/src/backend/app/db/schemas.py @@ -151,6 +151,7 @@ class BotChatResponse(BaseModel): success: bool = False strategy_needs_confirmation: Optional[bool] = False strategy_data: Optional[dict] = None + token_search_results: Optional[List[dict]] = None class SignalResponse(BaseModel): diff --git a/src/backend/app/services/ai_agent/conversational.py b/src/backend/app/services/ai_agent/conversational.py index 206523a..a7cabab 100644 --- a/src/backend/app/services/ai_agent/conversational.py +++ b/src/backend/app/services/ai_agent/conversational.py @@ -165,11 +165,42 @@ class ConversationalAgent: # Check if token_address is missing in strategy_update strategy_needs_confirmation = False + token_search_results = None + if strategy_update: + # Extract token name from conditions + token_name = None for cond in strategy_update.get("conditions", []): - if not cond.get("token_address"): + if not cond.get("token_address") and cond.get("token"): + token_name = cond.get("token") strategy_needs_confirmation = True break + + # Search for token if name is found + if strategy_needs_confirmation and token_name: + try: + from ..ave.client import AveCloudClient + from ...core.config import get_settings + settings = get_settings() + ave_client = AveCloudClient( + api_key=settings.AVE_API_KEY, + plan=settings.AVE_API_PLAN + ) + # Run async search in sync context + import asyncio + tokens = asyncio.run(ave_client.get_tokens(query=token_name, chain="bsc", limit=5)) + if tokens: + token_search_results = [ + { + "symbol": t.get("symbol", ""), + "name": t.get("name", ""), + "address": t.get("id") or t.get("contract_address", ""), + "chain": t.get("chain", "bsc") + } + for t in tokens + ] + except Exception as e: + print(f"Token search error: {e}") # Only update strategy if token_address is provided if strategy_update and strategy_needs_confirmation: @@ -181,6 +212,7 @@ class ConversationalAgent: "strategy_updated": False, "strategy_needs_confirmation": True, "strategy_data": strategy_update, + "token_search_results": token_search_results, "success": True } diff --git a/src/frontend/src/lib/api/types.ts b/src/frontend/src/lib/api/types.ts index 8be11cd..da30805 100644 --- a/src/frontend/src/lib/api/types.ts +++ b/src/frontend/src/lib/api/types.ts @@ -132,4 +132,12 @@ export interface BotChatResponse { success: boolean; strategy_needs_confirmation?: boolean; strategy_data?: StrategyConfig | null; + token_search_results?: TokenSearchResult[] | null; +} + +export interface TokenSearchResult { + symbol: string; + name: string; + address: string; + chain: string; } diff --git a/src/frontend/src/routes/bot/[id]/+page.svelte b/src/frontend/src/routes/bot/[id]/+page.svelte index ce6a960..6818dd0 100644 --- a/src/frontend/src/routes/bot/[id]/+page.svelte +++ b/src/frontend/src/routes/bot/[id]/+page.svelte @@ -5,6 +5,7 @@ import { isAuthenticated, isLoading, chatStore, addMessage, setMessages, clearChat, currentBotStore, setCurrentBot } from '$lib/stores'; import { api } from '$lib/api'; import { ChatInterface, StrategyPreview } from '$lib/components'; + import type { TokenSearchResult } from '$lib/api'; let botId = $derived($page.params.id); let isSending = $state(false); @@ -15,6 +16,7 @@ let pendingStrategyData = $state(null); let tokenAddressInput = $state(''); let confirmingMessage = $state(''); + let tokenSearchResults = $state([]); onMount(async () => { if (!$isAuthenticated && !$isLoading) { @@ -67,6 +69,7 @@ pendingStrategyData = response.strategy_data; confirmingMessage = response.response; tokenAddressInput = ''; + tokenSearchResults = response.token_search_results || []; showTokenConfirm = true; } @@ -134,12 +137,18 @@ showTokenConfirm = false; pendingStrategyData = null; tokenAddressInput = ''; + tokenSearchResults = []; + } + + function selectTokenResult(result: TokenSearchResult) { + tokenAddressInput = result.address; } function cancelTokenConfirm() { showTokenConfirm = false; pendingStrategyData = null; tokenAddressInput = ''; + tokenSearchResults = []; } @@ -151,9 +160,23 @@ {#if showTokenConfirm}