"""LangGraph (Python) trading-research agent with the YourAITools market-data tools as remote MCP servers.

Read-only market analytics for trading agents: no trading, no custody, no keys. The free MCP tier
returns previews; each answer names the paid x402 endpoint (USDC on Base / Polygon / Arbitrum / Solana)
for the full data. Nothing here is financial advice.

    pip install -r requirements.txt
    python trading_agent.py --list            # connect to every server and list its tools (no LLM)
    python trading_agent.py --smoke           # also call one free tool per server (no LLM, no wallet)
    OPENAI_API_KEY=sk-... python trading_agent.py "Is the BTC perp crowded long right now?"

Pick servers with TOOLS=perpradar,smartperps. Any LangChain chat model works:
set MODEL (default "openai:gpt-4.1-mini"), e.g. MODEL=anthropic:claude-sonnet-4-5.
"""
import asyncio
import json
import os
import sys

from langchain_mcp_adapters.client import MultiServerMCPClient

BASE = os.environ.get("YAT_BASE", "https://api.youraitools.co")
ALL = {
    "perpradar": "Perp funding rates, open interest and premium across Hyperliquid, dYdX v4, Paradex, Aevo",
    "tasignal": "RSI, MACD, EMAs, Bollinger, ATR, ADX, volatility; VaR and backtests on the paid tier",
    "smartperps": "What the most profitable Hyperliquid traders hold per coin (long/short, flows)",
    "tokenverdict": "Base ERC-20 safety check (honeypot / sell simulation, taxes, owner powers)",
    "solverdict": "Solana SPL / Token-2022 mint safety check",
    "payguard": "OFAC SDN screen before paying or approving an address",
}
PICK = [t.strip() for t in os.environ.get("TOOLS", ",".join(ALL)).split(",") if t.strip()]

# One free call per server for --smoke (tool name -> arguments); names are read from tools/list.
SMOKE = {
    "perpradar": {"symbol": "BTC"},
    "tasignal": {"symbol": "BTC", "timeframe": "1h"},
    "smartperps": {"symbol": "ETH"},
    "tokenverdict": {"token": "0x532f27101965dd16442E59d40670FaF5eBB142E4"},
    "solverdict": {"mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"},
    "payguard": {"address": "0x098B716B8Aaf21512996dC57EB0615e2383E2f96"},
}

PROMPT = """You are a careful crypto market research assistant for a trading agent.
Use the tools to gather facts (funding, open interest, indicators, smart-money positioning,
token safety) and report them plainly with the numbers and timestamps the tools return.
Never place trades, never tell the user what to buy or sell, never promise returns.
Say clearly when data is stale, partial or unavailable. This is not financial advice."""


def client():
    return MultiServerMCPClient({t: {"url": f"{BASE}/{t}/mcp", "transport": "streamable_http"} for t in PICK})


def first_line(result):
    if isinstance(result, list):  # MCP content blocks
        result = " ".join(b.get("text", "") if isinstance(b, dict) else str(b) for b in result)
    text = result if isinstance(result, str) else json.dumps(result, default=str)
    return text.splitlines()[0][:200] if text else ""


async def main(argv):
    c = client()
    if "--list" in argv or "--smoke" in argv:
        for t in PICK:
            tools = await c.get_tools(server_name=t)
            print(f"{t:13} {', '.join(x.name for x in tools)}")
            if "--smoke" in argv and tools and t in SMOKE:
                tool = tools[0]
                args = {k: v for k, v in SMOKE[t].items() if k in (tool.args or {})} or SMOKE[t]
                out = await tool.ainvoke(args)
                print(f"  {tool.name}({args}) -> {first_line(out)}")
        return
    from langgraph.prebuilt import create_react_agent  # imported here so --smoke needs no model provider
    agent = create_react_agent(os.environ.get("MODEL", "openai:gpt-4.1-mini"), await c.get_tools(), prompt=PROMPT)
    q = " ".join(a for a in argv if not a.startswith("--")) or "Summarize BTC perp funding and smart-money positioning."
    res = await agent.ainvoke({"messages": [{"role": "user", "content": q}]})
    print(res["messages"][-1].content)


if __name__ == "__main__":
    asyncio.run(main(sys.argv[1:]))
