diff --git a/_bmad-output/planning-artifacts/ux-design-specification.md b/_bmad-output/planning-artifacts/ux-design-specification.md
index fa62c51f8..5f6dde5d3 100644
--- a/_bmad-output/planning-artifacts/ux-design-specification.md
+++ b/_bmad-output/planning-artifacts/ux-design-specification.md
@@ -8,135 +8,66 @@ stepsCompleted:
- 6
- 7
- 8
+ - 9
+ - 14
inputDocuments:
- _bmad-output/planning-artifacts/prd.md
- _bmad-epics/epic-1-ai-powered-crypto-assistant.md
- _bmad-epics/epic-2-smart-monitoring-alerts.md
- - _bmad-epics/epic-3-trading-intelligence.md
- - _bmad-epics/epic-4-content-creation-productivity.md
----
+ - _bmad-epics/epic-3-trading-execution-safety.md
+ - _bmad-epics/epic-4-adaptive-learning-evolution.md
+outputDocument: _bmad-output/planning-artifacts/ux-design-specification.md
-# UX Design Specification SurfSense
+# UX Design Specification: SurfSense v2
-**Author:** Luis
-**Date:** 2026-02-02
+## 1. Design Strategy
+**"Evolution, Not Revolution"**
+- **Core Philosophy:** SurfSense v2 features will be "grafted" (injected) into the existing Research Dashboard rather than replacing it.
+- **Goal:** Maintain the professional, clean utility of the current "SaaS-style" research tool while adding "Crypto-Native" signals only where critical (the "Intel Layer").
+- **Visual Identity:** "Smart Cards" & "Traffic Lights" embedded in a Clean UI.
+
+## 2. Core User Experience
+**The "Intel Layer" Concept**
+- **Problem:** Users have to switch contexts between Charts (DexScreener) and Safety Scans (Scanners/Twitter).
+- **Solution:** A hybrid "Intel Layer" that sits *on top* of the chart or *inside* the research chat.
+- **Mental Model:** "Traffic Light System" (Red/Green/Yellow).
+ - 🔴 **Stop:** Scam/Rug/High Risk. (Immediate Action: Ignore)
+ - 🟢 **Go:** Safe/Whale Buying. (Immediate Action: Ape in/Research)
+ - 🟡 **Caution:** Mixed signals. (Action: Open Dashboard for Deep Dive)
+
+**Key Mechanics:**
+1. **Initiation:** Extension detects Token URL -> Shows Traffic Light Badge.
+2. **Interaction:** Click Badge -> Opens Overlay (Summary).
+3. **Deep Dive:** "Ask SurfSense" -> Redirects to existing Web Dashboard (Port 3999).
+4. **Integration:** Inside the Chat Interface, AI answers are formatted as **Rich UI Cards**, not just text.
+
+## 3. Visual Foundation (Confirmed Step 8 & 9)
+**Tokens & Theming**
+- **Source of Truth:** Inherited from existing `surfsense_web` (`globals.css` + Tailwind v4).
+- **Base Theme:** Dark Mode (Deep Navy / `#0B1221`) to match crypto aesthetic but cleaner.
+- **Typography:** Inter (Sans) for UI, Geist Mono for Data/Numbers.
+
+**Color Palette Extension (The "Traffic Light" Overlay)**
+* **Success (Buy/Safe):** `#22c55e` (Green-500) - Solid, trustworthy.
+* **Danger (Scam/Sell):** `#f43f5e` (Rose-500) - Urgent, alarming.
+* **Warning (Volatility):** `#f59e0b` (Amber-500) - Cautionary.
+* **Whale (Institutional):** `#3b82f6` (Blue-500) - Consistent with brand.
+
+## 4. Component Strategy (Smart Cards)
+Instead of building a full trading terminal, we build **"Injectable Components"**:
+1. **Signal Card:** Used in Chat & Extension. Shows Risk Score + 3 Key Bullets.
+2. **Whale Alert Row:** Used in Lists & Notifications. Shows "Wallet X bought $50K".
+3. **Mini-Chart:** Sparklines only, for quick trend context.
+
+## 5. Mobile & Responsive
+- **Extension:** Fixed width (360px-400px), focused on "At-a-glance" data.
+- **Web Dashboard:** Responsive, but optimized for Desktop Research. Mobile view converts Tables to Cards.
+
+## 6. Implementation Notes
+- **Frontend:** Next.js (Port 3999). Use standard Tailwind classes.
+- **Backend:** FastAPI (Port 3998). Serves structured JSON for UI Cards.
+- **Extension:** Chrome Side Panel API. Shares UI components with Web via Repo Monorepo/Shared Lib structure.
---
-
-
-
-## Executive Summary
-
-### Project Vision
-SurfSense 2.0 transforms from a general-purpose tool into a **specialized AI Co-pilot for Crypto Traders**. The core value proposition shifts from passive data aggregation to **proactive intelligence**—providing "Smart Monitoring," "Trading Intelligence," and "Content Creation" tools that work seamlessly alongside the trader's workflow.
-
-### Target Users
-* **Momentum Traders:** Need real-time, "hot" information (Whale alerts, Volume spikes) to catch rapid price movements. They prioritize speed and accessibility (Extension).
-* **Cautious Investors:** Prioritize safety and due diligence. They need tools to verify contracts, detect rug pulls, and analyze long-term metrics.
-* **Content Creators:** Use the platform to generate insights and share them (charts, threads) to build their audience.
-
-### Key Design Challenges (Web-First)
-* **Data Density vs. Clarity:** The new features (Portfolio, Market Intelligence) introduce complex data (charts, tables, metrics) that must be displayed without overwhelming the user, distinguishing this from the chat-heavy v1.
-* **Navigation Scalability:** The current chat-centric sidebar is insufficient for a multi-module application. We must integrate new functional areas (Market, Portfolio, Alerts) without burying them or cluttering the interface.
-* **Hybrid Workflow:** Users will constantly switch between "Deep Dive" analysis on the Web Dashboard and "Quick Checks" via the Extension. The experience must be consistent and synchronized.
-
-### Design Opportunities
-* **Hybrid Interface Structure:** Transitioning the Web Dashboard from a purely "Chat UI" to a **"Hybrid Interface"** that balances **App Modules** (for data/tools) with the **AI Assistant** (for query/support). This allows distinct spaces for "doing" (Trading/Monitoring) and "asking" (Chat).
-* **Unified Design System:** Leveraging the existing Web Design System (Tailwind/Shadcn) to rapidly build the Extension UI, ensuring a consistent look and feel while reducing development effort ($18K constraint).
-
-## Core User Experience
-
-### Defining Experience: "The Intel Layer"
-SurfSense is not where users go to *see* price (they use DexScreener for that), but where they go to *see* **The Truth**. The defining interaction is an **"Instant Reality Check"**: while the chart shows hype (FOMO), SurfSense overlays the cold, hard data (Risk/Whale movement), allowing users to verify a trade in seconds. It acts as the "Verify" step in the "Detect → Verify → Act" loop.
-
-### User Mental Model
-* **The Old Way:** See price spike → Check Twitter (hype) → Search Contract (manual) → Check Holders → Panic/FOMO → Buy blindly.
-* **The SurfSense Way:** See price spike → **Glance at Extension (Traffic Light)**:
- * 🔴 **Red:** Ignore immediately (Rug/Honeypot). Time saved: 10 mins.
- * 🟢 **Green:** Trade with confidence.
- * 🟡 **Yellow:** "Investigate" → One click to open Web Dashboard for deep reasoning (Whale behavior, Fresh wallet movement).
-
-### Platform Strategy
-* **Web Dashboard (Master):** The "Command Center" for Portfolio, Alert Management, and Deep Intelligence Analysis. Focuses on **textual/numerical insights** over graphical charts.
-* **Extension (Satellite):** The "Tactical" tool for instant context. Smartly advises the user based on their current active tab using the **"Symbiotic Side-Panel"** pattern (lives alongside the chart, doesn't block it).
-
-### Experience Mechanics
-1. **Initiation:** User navigates to a token on DexScreener/Twitter.
-2. **Interaction:** Extension Badge updates color (Red/Green). User clicks for Summary Overlay.
-3. **Cross-Over:** User clicks "Open Dashboard" for deep dive (if needed). Web App opens to the exact token context.
-4. **Completion:** User executes trade on DexScreener (or bot) with full confidence.
-
-### Success Criteria
-* **Time-to-Truth < 5s:** User determines safety (SCAM vs LEGIT) within 5 seconds of landing on a chart.
-* **"Savior" Frequency:** User experiences a "saved me from a rug" moment at least once per week.
-* **Zero-Context Switching:** User never manually copies a contract address; the system auto-detects context.
-
-### Novel UX Patterns
-* **"Evidence-First" AI:** Insights are always coupled with proof (e.g., "Bullish *because* 3 whales bought" with links to txns), avoiding "Black Box" trust issues.
-* **Traffic Light Risk Coding:** Universal color cues (Green=Safe, Yellow=Caution, Red=Danger) for Risk Scores allow scanning in < 1 second.
-
-## Desired Emotional Response
-
-### Primary Emotional Goals
-* **Confidence (Tự tin):** Users feel they possess "Insider Intelligence" that others missing by relying solely on charts. The AI provides the "Why" behind the price action.
-* **Calm (Bình tĩnh):** In a chaotic market (FOMO, rapid candles), SurfSense acts as a stabilizing anchor, providing "Cold Hard Data" (Risk Scores, On-chain metrics) to rationalize decision-making.
-* **Clarity (Sự rõ ràng):** Cutting through the noise of social media and complex charts to show the simple truth about a token's safety and potential.
-
-### Emotional Journey Mapping
-* **Trigger (Alert):** **Urgency & Curiosity.** "Whale Accumulating" alert sparks immediate interest but balanced with a need to know *why*.
-* **Action (Verify):** **Reassurance.** Opening the dashboard confirms safety (Verified Contract) and validates the trend (AI Sentiment). Confusion turns into clarity.
-* **Result (Decision):** **Superiority & Relief.** User feels smarter than the herd ("I avoided a rug pull" or "I caught a trend early").
-
-## UX Pattern Analysis & Inspiration
-
-### Inspiring Products Analysis
-* **DexScreener (Crypto):** Excellent **Data Density**. They maximize screen real estate to show price, txns, and liquidity simultaneously without clutter. *Inspiration: High-density layouts using color coding (Green/Red) to direct attention.*
-* **GMGN.ai (Crypto):** Strong **Risk Visualization**. They surface hidden risks (dev dumping, high holder concentration) prominently. *Inspiration: "Warning Badges" and "Risk Clusters" that are impossible to ignore.*
-* **Perplexity AI (Non-Crypto):** Mastering **Trust & Citations**. Every AI claim is backed by a source link. *Inspiration: SurfSense AI insights should link back to source data (e.g., "Whale bought" -> Link to Txn).*
-* **Linear (Productivity):** **Keyboard-First Navigation** and speed. *Inspiration: Power user shortcuts (Cmd+K) for quick search and navigation between modules.*
-
-### Key Takeaways
-* **Terminal-Style Efficiency:** Use a dense, tabular view for the "Market Intelligence" module (Web Dashboard) to allow sorting/filtering of 50+ tokens instantly.
-* **No Chart, Just Intel:** Don't replicate DexScreener. Provide the "Why" (Insights) behind the "What" (Price).
-
-## Design System Foundation
-
-### 1.1 Design System Choice
-**Shadcn/UI + Tailwind CSS** (Confirmed Existing Stack).
-
-### Rationale for Selection
-* **Consistency:** The existing `surfsense_web` frontend already utilizes Tailwind CSS (v4) and Shadcn/UI components (Radix primitives). Maintaining this stack ensures zero friction between the current codebase and new v2 features.
-* **Inheritance:** The Extension (Slave) will directly inherit color tokens and typography from the Web Dashboard's `tailwind.config.js`, ensuring a unified brand experience with minimal effort.
-
-### Implementation Approach
-* **Web-First Truth:** The Web Dashboard remains the "Master" for design tokens and component definitions.
-* **Dark Mode Native:** The system is already optimized for Dark Mode, which aligns perfectly with the crypto trading persona.
-* **Customization:** Extend default Shadcn theme with "Signal Colors" (Neon Green, Alert Red) for financial data visualization.
-
-## Visual Design Foundation
-
-### Color System
-* **Core Palette (Inherited):** Maintain established `globals.css` structure (OKLCH variables) for 100% implementation speed.
- * Background: `oklch(0.145 0 0)` (Dark Gray) for enterprise-grade stability.
- * Foreground: `oklch(0.985 0 0)` (White).
-* **Signal Colors (New):** High-saturation "Neon" variants for "Traffic Light" indicators in Dark Mode.
- * 🟢 **Success:** `oklch(0.6 0.18 145)` (Neon Green) - Use for "Safe", "Verified", "Buy Signal".
- * 🔴 **Danger:** `oklch(0.6 0.2 25)` (Neon Red) - Use for "Scam", "Rug Risk", "Sell Signal".
- * 🟡 **Warning:** `oklch(0.8 0.15 85)` (Amber) - Use for "Caution", "Low Liquidity".
-
-### Typography System
-* **Primary Font:** **Geist Sans** (Inherited).
- * *Rationale:* Optimized for Vercel/Next.js stack, zero layout shift, and includes excellent **tabular figures** for price data.
- * *Usage:* All UI text, headers, and especially data tables.
-* **Tone:** Professional, direct, data-first. No decorative serifs.
-
-### Spacing & Layout Foundation
-* **Base Unit:** `0.25rem` (4px). Standard Tailwind grid.
-* **Radius:** `0.625rem` (Default) for cards/inputs to match existing Web UI.
-* **Density Strategy:**
- * **Extension:** "Standard" density for touch/click friendliness.
- * **Market Intelligence (Web):** "Compact" density to maximize rows per screen (Terminal feel).
-
-### Accessibility Considerations
-* **High Contrast Signals:** Prioritize distinctive colors for status indicators (Red/Green) but ensure they are accompanied by text/icon labels (not color-only) to support color-blind users.
-* **Dark Mode Optimization:** Ensure text contrast remains high (AA standard) against the dark gray background.
+**Status:** ✅ APPROVED
+**Next Steps:** Proceed to Architecture Design to map these UI components to Backend APIs.
diff --git a/surfsense_backend/app/agents/new_chat/tools/__init__.py b/surfsense_backend/app/agents/new_chat/tools/__init__.py
index 9e1a4f19c..3b29dd180 100644
--- a/surfsense_backend/app/agents/new_chat/tools/__init__.py
+++ b/surfsense_backend/app/agents/new_chat/tools/__init__.py
@@ -13,10 +13,16 @@ Available tools:
- scrape_webpage: Extract content from webpages
- save_memory: Store facts/preferences about the user
- recall_memory: Retrieve relevant user memories
+- get_live_token_price: Get real-time crypto price from DexScreener
+- get_live_token_data: Get comprehensive real-time crypto market data
"""
# Registry exports
# Tool factory exports (for direct use)
+from .crypto_realtime import (
+ create_get_live_token_data_tool,
+ create_get_live_token_price_tool,
+)
from .display_image import create_display_image_tool
from .knowledge_base import (
CONNECTOR_DESCRIPTIONS,
@@ -48,6 +54,8 @@ __all__ = [
# Tool factories
"create_display_image_tool",
"create_generate_podcast_tool",
+ "create_get_live_token_data_tool",
+ "create_get_live_token_price_tool",
"create_link_preview_tool",
"create_recall_memory_tool",
"create_save_memory_tool",
diff --git a/surfsense_backend/app/agents/new_chat/tools/crypto_realtime.py b/surfsense_backend/app/agents/new_chat/tools/crypto_realtime.py
new file mode 100644
index 000000000..52006f03e
--- /dev/null
+++ b/surfsense_backend/app/agents/new_chat/tools/crypto_realtime.py
@@ -0,0 +1,322 @@
+"""
+Real-time cryptocurrency data tools for the SurfSense agent.
+
+This module provides tools for fetching LIVE crypto data directly from DexScreener API.
+These tools complement the RAG-based search_knowledge_base tool:
+- RAG (search_knowledge_base): Historical context, trends, analysis from indexed data
+- Real-time tools: Current prices, live market data
+
+The AI agent decides which to use based on the query:
+- "What's the current price of BULLA?" → get_live_token_price (real-time)
+- "How has BULLA performed this week?" → search_knowledge_base (RAG)
+- "Analyze BULLA for me" → Both (RAG for context + real-time for current data)
+"""
+
+import hashlib
+import logging
+from typing import Any
+
+from langchain_core.tools import tool
+
+from app.connectors.dexscreener_connector import DexScreenerConnector
+
+logger = logging.getLogger(__name__)
+
+
+def generate_token_id(chain: str, address: str) -> str:
+ """Generate a unique ID for a token query."""
+ hash_val = hashlib.md5(f"{chain}:{address}".encode()).hexdigest()[:12]
+ return f"token-{hash_val}"
+
+
+def create_get_live_token_price_tool():
+ """
+ Factory function to create the get_live_token_price tool.
+
+ This tool fetches REAL-TIME price data directly from DexScreener API.
+ Use this when users ask for current/live prices.
+
+ Returns:
+ A configured tool function for fetching live token prices.
+ """
+
+ @tool
+ async def get_live_token_price(
+ chain: str,
+ token_address: str,
+ token_symbol: str | None = None,
+ ) -> dict[str, Any]:
+ """
+ Get the LIVE/CURRENT price of a cryptocurrency token from DexScreener.
+
+ Use this tool when the user asks for:
+ - Current price: "What's the price of BULLA right now?"
+ - Live data: "Show me live price for SOL"
+ - Real-time info: "What's WETH trading at?"
+
+ DO NOT use this for historical analysis - use search_knowledge_base instead.
+
+ Args:
+ chain: Blockchain network (e.g., 'solana', 'ethereum', 'base', 'bsc')
+ token_address: The token's contract address
+ token_symbol: Optional token symbol for display (e.g., 'BULLA', 'SOL')
+
+ Returns:
+ Dictionary with live price data including:
+ - price_usd: Current price in USD
+ - price_change_24h: 24-hour price change percentage
+ - price_change_1h: 1-hour price change percentage
+ - volume_24h: 24-hour trading volume
+ - liquidity_usd: Total liquidity in USD
+ - market_cap: Market capitalization
+ - dex: DEX where the best liquidity is found
+ - pair_url: Link to DexScreener chart
+ """
+ token_id = generate_token_id(chain, token_address)
+
+ try:
+ # Initialize DexScreener connector
+ connector = DexScreenerConnector()
+
+ # Fetch live data from API
+ pairs, error = await connector.get_token_pairs(chain, token_address)
+
+ if error:
+ logger.warning(f"[get_live_token_price] Error: {error}")
+ return {
+ "id": token_id,
+ "kind": "live_token_price",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": error,
+ }
+
+ if not pairs:
+ return {
+ "id": token_id,
+ "kind": "live_token_price",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": f"No trading pairs found for {token_symbol or token_address} on {chain}",
+ }
+
+ # Get the best pair (highest liquidity)
+ best_pair = max(pairs, key=lambda p: float(p.get("liquidity", {}).get("usd", 0) or 0))
+
+ # Extract data from best pair
+ base_token = best_pair.get("baseToken", {})
+ price_change = best_pair.get("priceChange", {})
+ volume = best_pair.get("volume", {})
+ liquidity = best_pair.get("liquidity", {})
+
+ return {
+ "id": token_id,
+ "kind": "live_token_price",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol or base_token.get("symbol", "Unknown"),
+ "token_name": base_token.get("name", "Unknown"),
+ "price_usd": best_pair.get("priceUsd", "N/A"),
+ "price_native": best_pair.get("priceNative", "N/A"),
+ "price_change_5m": price_change.get("m5", 0),
+ "price_change_1h": price_change.get("h1", 0),
+ "price_change_6h": price_change.get("h6", 0),
+ "price_change_24h": price_change.get("h24", 0),
+ "volume_24h": volume.get("h24", 0),
+ "volume_6h": volume.get("h6", 0),
+ "volume_1h": volume.get("h1", 0),
+ "liquidity_usd": liquidity.get("usd", 0),
+ "market_cap": best_pair.get("marketCap", 0),
+ "fdv": best_pair.get("fdv", 0),
+ "dex": best_pair.get("dexId", "Unknown"),
+ "pair_address": best_pair.get("pairAddress", ""),
+ "pair_url": best_pair.get("url", ""),
+ "total_pairs": len(pairs),
+ "data_source": "DexScreener API (Real-time)",
+ }
+
+ except Exception as e:
+ error_message = str(e)
+ logger.error(f"[get_live_token_price] Error fetching {chain}/{token_address}: {error_message}")
+ return {
+ "id": token_id,
+ "kind": "live_token_price",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": f"Failed to fetch live price: {error_message[:100]}",
+ }
+
+ return get_live_token_price
+
+
+def create_get_live_token_data_tool():
+ """
+ Factory function to create the get_live_token_data tool.
+
+ This tool fetches comprehensive REAL-TIME market data from DexScreener API.
+ Use this when users want detailed current market information.
+
+ Returns:
+ A configured tool function for fetching live token market data.
+ """
+
+ @tool
+ async def get_live_token_data(
+ chain: str,
+ token_address: str,
+ token_symbol: str | None = None,
+ include_all_pairs: bool = False,
+ ) -> dict[str, Any]:
+ """
+ Get comprehensive LIVE market data for a cryptocurrency token.
+
+ Use this tool when the user asks for:
+ - Detailed market info: "Show me full market data for BULLA"
+ - Trading activity: "What's the trading volume for SOL?"
+ - Liquidity info: "How much liquidity does WETH have?"
+ - Transaction counts: "How many buys/sells for this token?"
+
+ This returns more detailed data than get_live_token_price.
+ For historical trends and analysis, use search_knowledge_base instead.
+
+ Args:
+ chain: Blockchain network (e.g., 'solana', 'ethereum', 'base', 'bsc')
+ token_address: The token's contract address
+ token_symbol: Optional token symbol for display
+ include_all_pairs: If True, include data from all trading pairs
+
+ Returns:
+ Dictionary with comprehensive market data including:
+ - All price data from get_live_token_price
+ - Transaction counts (buys/sells in 24h, 6h, 1h)
+ - All trading pairs (if include_all_pairs=True)
+ - Aggregated volume across all pairs
+ """
+ token_id = generate_token_id(chain, token_address)
+
+ try:
+ # Initialize DexScreener connector
+ connector = DexScreenerConnector()
+
+ # Fetch live data from API
+ pairs, error = await connector.get_token_pairs(chain, token_address)
+
+ if error:
+ logger.warning(f"[get_live_token_data] Error: {error}")
+ return {
+ "id": token_id,
+ "kind": "live_token_data",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": error,
+ }
+
+ if not pairs:
+ return {
+ "id": token_id,
+ "kind": "live_token_data",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": f"No trading pairs found for {token_symbol or token_address} on {chain}",
+ }
+
+ # Get the best pair (highest liquidity)
+ best_pair = max(pairs, key=lambda p: float(p.get("liquidity", {}).get("usd", 0) or 0))
+
+ # Extract data from best pair
+ base_token = best_pair.get("baseToken", {})
+ price_change = best_pair.get("priceChange", {})
+ volume = best_pair.get("volume", {})
+ liquidity = best_pair.get("liquidity", {})
+ txns = best_pair.get("txns", {})
+
+ # Calculate aggregated stats across all pairs
+ total_volume_24h = sum(float(p.get("volume", {}).get("h24", 0) or 0) for p in pairs)
+ total_liquidity = sum(float(p.get("liquidity", {}).get("usd", 0) or 0) for p in pairs)
+ total_buys_24h = sum(p.get("txns", {}).get("h24", {}).get("buys", 0) or 0 for p in pairs)
+ total_sells_24h = sum(p.get("txns", {}).get("h24", {}).get("sells", 0) or 0 for p in pairs)
+
+ result = {
+ "id": token_id,
+ "kind": "live_token_data",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol or base_token.get("symbol", "Unknown"),
+ "token_name": base_token.get("name", "Unknown"),
+ # Price data
+ "price_usd": best_pair.get("priceUsd", "N/A"),
+ "price_native": best_pair.get("priceNative", "N/A"),
+ "price_change_5m": price_change.get("m5", 0),
+ "price_change_1h": price_change.get("h1", 0),
+ "price_change_6h": price_change.get("h6", 0),
+ "price_change_24h": price_change.get("h24", 0),
+ # Volume data (best pair)
+ "volume_24h": volume.get("h24", 0),
+ "volume_6h": volume.get("h6", 0),
+ "volume_1h": volume.get("h1", 0),
+ "volume_5m": volume.get("m5", 0),
+ # Liquidity
+ "liquidity_usd": liquidity.get("usd", 0),
+ "liquidity_base": liquidity.get("base", 0),
+ "liquidity_quote": liquidity.get("quote", 0),
+ # Market metrics
+ "market_cap": best_pair.get("marketCap", 0),
+ "fdv": best_pair.get("fdv", 0),
+ # Transaction counts (best pair)
+ "txns_24h_buys": txns.get("h24", {}).get("buys", 0),
+ "txns_24h_sells": txns.get("h24", {}).get("sells", 0),
+ "txns_6h_buys": txns.get("h6", {}).get("buys", 0),
+ "txns_6h_sells": txns.get("h6", {}).get("sells", 0),
+ "txns_1h_buys": txns.get("h1", {}).get("buys", 0),
+ "txns_1h_sells": txns.get("h1", {}).get("sells", 0),
+ # Aggregated stats (all pairs)
+ "total_volume_24h_all_pairs": total_volume_24h,
+ "total_liquidity_all_pairs": total_liquidity,
+ "total_buys_24h_all_pairs": total_buys_24h,
+ "total_sells_24h_all_pairs": total_sells_24h,
+ # DEX info
+ "dex": best_pair.get("dexId", "Unknown"),
+ "pair_address": best_pair.get("pairAddress", ""),
+ "pair_url": best_pair.get("url", ""),
+ "pair_created_at": best_pair.get("pairCreatedAt"),
+ # Metadata
+ "total_pairs": len(pairs),
+ "data_source": "DexScreener API (Real-time)",
+ }
+
+ # Include all pairs if requested
+ if include_all_pairs and len(pairs) > 1:
+ result["all_pairs"] = [
+ {
+ "dex": p.get("dexId"),
+ "pair_address": p.get("pairAddress"),
+ "quote_symbol": p.get("quoteToken", {}).get("symbol"),
+ "price_usd": p.get("priceUsd"),
+ "liquidity_usd": p.get("liquidity", {}).get("usd", 0),
+ "volume_24h": p.get("volume", {}).get("h24", 0),
+ "url": p.get("url"),
+ }
+ for p in sorted(pairs, key=lambda x: float(x.get("liquidity", {}).get("usd", 0) or 0), reverse=True)[:10]
+ ]
+
+ return result
+
+ except Exception as e:
+ error_message = str(e)
+ logger.error(f"[get_live_token_data] Error fetching {chain}/{token_address}: {error_message}")
+ return {
+ "id": token_id,
+ "kind": "live_token_data",
+ "chain": chain,
+ "token_address": token_address,
+ "token_symbol": token_symbol,
+ "error": f"Failed to fetch live data: {error_message[:100]}",
+ }
+
+ return get_live_token_data
+
diff --git a/surfsense_backend/app/agents/new_chat/tools/registry.py b/surfsense_backend/app/agents/new_chat/tools/registry.py
index c65445419..f4d0b008b 100644
--- a/surfsense_backend/app/agents/new_chat/tools/registry.py
+++ b/surfsense_backend/app/agents/new_chat/tools/registry.py
@@ -43,6 +43,10 @@ from typing import Any
from langchain_core.tools import BaseTool
+from .crypto_realtime import (
+ create_get_live_token_data_tool,
+ create_get_live_token_price_tool,
+)
from .display_image import create_display_image_tool
from .knowledge_base import create_search_knowledge_base_tool
from .link_preview import create_link_preview_tool
@@ -179,6 +183,26 @@ BUILTIN_TOOLS: list[ToolDefinition] = [
# factory=lambda deps: create_my_custom_tool(...),
# requires=["search_space_id"],
# ),
+ # =========================================================================
+ # CRYPTO REAL-TIME TOOLS - Hybrid approach (RAG + Real-time)
+ # =========================================================================
+ # These tools fetch LIVE data directly from DexScreener API.
+ # Use alongside search_knowledge_base for comprehensive crypto analysis:
+ # - search_knowledge_base: Historical context, trends (from indexed data)
+ # - get_live_token_price: Current price (real-time API call)
+ # - get_live_token_data: Full market data (real-time API call)
+ ToolDefinition(
+ name="get_live_token_price",
+ description="Get LIVE/CURRENT cryptocurrency price from DexScreener API. Use for real-time price queries.",
+ factory=lambda deps: create_get_live_token_price_tool(),
+ requires=[],
+ ),
+ ToolDefinition(
+ name="get_live_token_data",
+ description="Get comprehensive LIVE market data (price, volume, liquidity, transactions) from DexScreener API.",
+ factory=lambda deps: create_get_live_token_data_tool(),
+ requires=[],
+ ),
]
diff --git a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
index 803bd6661..c3831851b 100644
--- a/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
+++ b/surfsense_web/app/dashboard/[search_space_id]/new-chat/[[...chat_id]]/page.tsx
@@ -39,6 +39,23 @@ import { GeneratePodcastToolUI } from "@/components/tool-ui/generate-podcast";
import { LinkPreviewToolUI } from "@/components/tool-ui/link-preview";
import { ScrapeWebpageToolUI } from "@/components/tool-ui/scrape-webpage";
import { RecallMemoryToolUI, SaveMemoryToolUI } from "@/components/tool-ui/user-memory";
+// Crypto Tool UI Components - Conversational Crypto Advisor
+import {
+ TokenAnalysisToolUI,
+ WatchlistDisplayToolUI,
+ ActionConfirmationToolUI,
+ AlertConfigurationToolUI,
+ ProactiveAlertToolUI,
+ TrendingTokensToolUI,
+ WhaleActivityToolUI,
+ MarketOverviewToolUI,
+ HolderAnalysisToolUI,
+ PortfolioDisplayToolUI,
+ UserProfileToolUI,
+ // Real-time crypto tools (Hybrid approach: RAG + Real-time)
+ LiveTokenPriceToolUI,
+ LiveTokenDataToolUI,
+} from "@/components/tool-ui/crypto";
import { Spinner } from "@/components/ui/spinner";
import { useChatSessionStateSync } from "@/hooks/use-chat-session-state";
import { useMessagesElectric } from "@/hooks/use-messages-electric";
@@ -1458,6 +1475,21 @@ export default function NewChatPage() {
{label}
++ {isPositive ? "+" : ""}{value.toFixed(2)}% +
+
+
{formatLargeNumber(result?.volume_24h)}
+
+
{formatLargeNumber(result?.liquidity_usd)}
+Market Cap
+{formatLargeNumber(result?.market_cap)}
+FDV
+{formatLargeNumber(result?.fdv)}
+
+
{label}
++ {isPositive ? "+" : ""}{value.toFixed(2)}% +
+