mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-04-27 17:56:25 +02:00
- Added UX strategy: Extension for Quick Actions, Frontend for Management - Organized features into 4 phases (Phase 1 completed) - Added 14 new extension features (FR-EXT-07 to FR-EXT-17): * Smart Monitoring: Price alerts, whale tracking, rug pull detection * Trading Intelligence: Token analysis, entry/exit suggestions, portfolio tracker * Content Creation: Chart screenshots, AI thread generator * Productivity: Quick actions, notifications, keyboard shortcuts - Added Feature Responsibility Matrix showing Extension vs Frontend roles - Added Settings Sync strategy (FR-EXT-06) with deep links to frontend - Documented state sync architecture: Extension ↔ Backend API ↔ Frontend
143 lines
4.7 KiB
Python
143 lines
4.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Integration test script for Chat RAG with DexScreener.
|
|
Tests the full loop: login -> create thread -> send query -> verify response.
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
import sys
|
|
import time
|
|
|
|
BASE_URL = "http://localhost:8000"
|
|
|
|
def login(email: str, password: str) -> str:
|
|
"""Login and return JWT access token."""
|
|
print(f"🔐 Logging in as {email}...")
|
|
response = requests.post(
|
|
f"{BASE_URL}/auth/jwt/login",
|
|
data={"username": email, "password": password},
|
|
headers={"Content-Type": "application/x-www-form-urlencoded"}
|
|
)
|
|
|
|
if response.status_code != 200:
|
|
print(f"❌ Login failed: {response.status_code}")
|
|
print(response.text)
|
|
sys.exit(1)
|
|
|
|
data = response.json()
|
|
token = data.get("access_token")
|
|
print(f"✅ Login successful!")
|
|
return token
|
|
|
|
def create_thread(token: str, space_id: int = 7) -> int:
|
|
"""Create a new chat thread."""
|
|
print(f"\n📝 Creating thread in search_space_id={space_id}...")
|
|
|
|
# First ensure we have a thread or create one
|
|
# If the API requires just a thread ID, we ask for one.
|
|
response = requests.post(
|
|
f"{BASE_URL}/api/v1/threads",
|
|
json={"search_space_id": space_id},
|
|
headers={"Authorization": f"Bearer {token}"}
|
|
)
|
|
|
|
if response.status_code not in [200, 201]:
|
|
print(f"⚠️ Create thread failed: {response.status_code}")
|
|
# Try listing threads and picking one?
|
|
# For now, exit
|
|
# print(response.text)
|
|
return 1 # Fallback ID
|
|
|
|
data = response.json()
|
|
thread_id = data.get("id")
|
|
print(f"✅ Thread created: {thread_id}")
|
|
return thread_id
|
|
|
|
def test_chat_query(token: str, thread_id: int, query: str) -> bool:
|
|
"""Send a chat query and check response."""
|
|
print(f"\n💬 Sending query: '{query}'...")
|
|
|
|
payload = {
|
|
"chat_id": thread_id, # The API expects 'chat_id', not 'thread_id'
|
|
"user_query": query, # The API expects 'user_query', not 'query'
|
|
"search_space_id": 7,
|
|
}
|
|
|
|
# We use stream=False for easier testing, or handle SSE if needed.
|
|
# Assuming the backend supports non-streaming execution via /new_chat or similar
|
|
# The Implementation Plan mentioned POST /api/v1/new_chat
|
|
|
|
response = requests.post(
|
|
f"{BASE_URL}/api/v1/new_chat",
|
|
json=payload,
|
|
headers={"Authorization": f"Bearer {token}"},
|
|
stream=True
|
|
)
|
|
|
|
print(f"Status: {response.status_code}")
|
|
|
|
if response.status_code != 200:
|
|
print(f"❌ Chat request failed: {response.text}")
|
|
return False
|
|
|
|
# Handle stream or full response
|
|
full_text = ""
|
|
print("Stream output:")
|
|
for line in response.iter_lines():
|
|
if line:
|
|
line_str = line.decode('utf-8')
|
|
if line_str.startswith("data: "):
|
|
try:
|
|
data = json.loads(line_str[6:])
|
|
# Handle Vercel AI SDK compatible format
|
|
if data.get("type") == "text-delta" and "delta" in data:
|
|
chunk = data["delta"]
|
|
full_text += chunk
|
|
print(chunk, end="", flush=True)
|
|
elif "answer" in data: # Fallback/Legacy
|
|
chunk = data["answer"]
|
|
full_text += chunk
|
|
print(chunk, end="", flush=True)
|
|
elif data.get("type") == "error":
|
|
print(f"\n[ERROR] Stream error: {data}")
|
|
except Exception as e:
|
|
pass # Ignore parse errors for non-JSON lines like [DONE]
|
|
|
|
print("\n\n✅ Full Response Received.")
|
|
print("-" * 40)
|
|
print(full_text)
|
|
print("-" * 40)
|
|
|
|
# Verification
|
|
if "$" in full_text and any(x in full_text.lower() for x in ["price", "usd"]):
|
|
print("✅ PASSED: Response contains price information.")
|
|
return True
|
|
else:
|
|
print("⚠️ WARNING: Response might not contain price info.")
|
|
return False
|
|
|
|
def main():
|
|
print("=" * 60)
|
|
print("Chat RAG Verification (DexScreener)")
|
|
print("=" * 60)
|
|
|
|
token = login("admin@surfsense.ai", "password123")
|
|
|
|
# Step 2: Create Thread
|
|
# Note: Using search_space_id=1 for verifying if default space works or 7 if specific
|
|
# Implementation plan said 7.
|
|
thread_id = create_thread(token, space_id=7)
|
|
|
|
# Step 3: Chat Query
|
|
success = test_chat_query(token, thread_id, "What is the price of WETH on Ethereum?")
|
|
|
|
if success:
|
|
print("\n🎉 Verification Successful!")
|
|
sys.exit(0)
|
|
else:
|
|
print("\n❌ Verification Failed")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main()
|