Commit Graph

27 Commits

Author SHA1 Message Date
shinchan-zhai
574e5602c1 fix: Lighter CancelStopOrders now filters by TriggerPrice, proxyBinance checks upstream status
- CancelStopOrders: only cancel orders with non-empty TriggerPrice (was canceling ALL orders including regular limit orders — safety bug)
- proxyBinance: return 502 when upstream returns non-200 instead of silently proxying error pages
- Remove redundant CORS headers in agent/web.go (already handled by gin middleware)
2026-03-25 01:05:54 +08:00
shinchan-zhai
d00e43af1c fix: Bybit shared HTTP client, auth token bugs, consistent safe.ReadAllLimited
- Bybit: replace http.Get/http.DefaultClient with shared bybitHTTPClient (30s timeout, connection pooling)
- Frontend: fix resetPassword missing auth token (endpoint now requires auth)
- Frontend: fix SettingsPage using wrong localStorage key ('token' → 'auth_token')
- Agent: migrate remaining io.ReadAll(io.LimitReader()) to safe.ReadAllLimited for consistency
- Remove unused 'io' imports from brain.go and sentinel.go
2026-03-25 01:05:54 +08:00
shinchan-zhai
149f228bec robustness: shared HTTP client, HTTP status checks, abort controller, streaming perf
- web.go: reuse shared binanceClient with connection pooling instead of per-request client
- sentinel.go: check HTTP status code before parsing Binance ticker response
- brain.go: check HTTP status codes in news scan and market brief APIs
- brain.go: add cleanStaleSignals() to prevent unbounded sync.Map growth
- scheduler.go: periodically clean expired pending trades
- AgentChatPage.tsx: add AbortController to cancel in-flight requests
- AgentChatPage.tsx: check response.ok before parsing JSON
- AgentChatPage.tsx: batch word streaming (~40 frames max) to reduce re-renders
- AgentChatPage.tsx: handle AbortError gracefully (remove orphan bot message)
2026-03-25 01:05:54 +08:00
shinchan-zhai
456570c37c security: add safe.ReadAllLimited — bound all HTTP response body reads to 10MB
- Created safe/io.go with ReadAllLimited helper (default 10MB limit)
- Replaced 62 unbounded io.ReadAll(resp.Body) calls across 32 files
- Covers all exchange traders (Hyperliquid, Bybit, Binance, OKX, Aster,
  KuCoin, Gate, Bitget, Lighter, Indodax), providers (CoinAnk, Alpaca,
  TwelveData), MCP client/x402, market data, wallet, telegram, kernel
- Prevents OOM from malicious/buggy exchange API responses
- Previously fixed: brain.go, sentinel.go already had manual LimitReader
2026-03-25 01:05:54 +08:00
shinchan-zhai
fd28aa7fc6 reliability: wrap all 27 bare goroutines with safe.Go/GoNamed panic recovery
Applied safe.GoNamed to:
- 9 exchange order_sync goroutines (OKX, Hyperliquid, Aster, Bybit, KuCoin, Gate, Bitget, Lighter, Binance×2)
- Drawdown monitor (auto_trader_risk.go)
- Brain news scanner + market briefs (agent/brain.go)
- Sentinel scanner (agent/sentinel.go)
- Agent scheduler (agent/scheduler.go)
- x402 idle watchdog (mcp/payment/x402.go)
- MCP stream idle watchdog (mcp/client.go)
- Rate limiter cleanup (api/rate_limiter.go)
- 3 telemetry fire-and-forget sends (telemetry/experience.go)
- CoinAnk WS handler (provider/coinank/coinank_api/kline_ws.go)
- API server goroutine (main.go)

Added manual defer/recover with error reporting to:
- Telegram AI agent handler (sends error msg to user on panic)
- Trader data fetch (returns error result on panic to prevent deadlock)

Before: a panic in ANY of these 27 goroutines would crash the entire
trading process with zero diagnostics. Now all panics are caught, logged
with stack traces, and the process continues running.
2026-03-25 01:05:54 +08:00
shinchan-zhai
9a81fa5e84 fix: news seen map eviction strategy — keep half instead of clearing all
Previously when the seen map exceeded 1000 entries, ALL entries were
deleted, losing dedup state and causing re-notifications. Now evicts
~half the entries, preserving recent URLs for dedup continuity.
2026-03-25 01:05:54 +08:00
shinchan-zhai
6acf925a0b security: configurable CORS origins, limit sentinel response body
- Add CORS_ALLOWED_ORIGINS config (comma-separated origins, default allow-all)
- CORS middleware now validates Origin header against allowlist
- Add io.LimitReader to sentinel.go (was unbounded, now 256KB)
- Include previous: agent chat auth middleware + frontend token header
2026-03-25 01:05:54 +08:00
shinchan-zhai
f28f0e340c security: login rate limiting, fix health endpoint, harden error handling
- Fix health endpoint returning null time (use time.Now() instead of context value)
- Add LoginRateLimiter: 5 attempts per 15min window, 5min block on brute-force
- Apply rate limiting to login/register endpoints
- Move reset-password to authenticated routes (was unauthenticated — critical vuln)
- Limit response body sizes on proxy/external API calls (prevent memory exhaustion)
- Sanitize error messages in agent chat endpoint (don't leak internal errors)
- Record login success/failure for rate limiting tracking
2026-03-25 01:05:54 +08:00
shinchan-zhai
0f67747b0c fix: enforce tool-based data only — Agent can no longer fabricate prices
- System prompt now has absolute rule: no tool result = no price
- Pre-market overview must call search_stock for each major stock
- Index futures explicitly marked as unsupported
- Training data prices explicitly declared outdated and forbidden
- Applied to both CN and EN prompts
2026-03-25 01:05:54 +08:00
shinchan-zhai
b1500f9e9a fix: prevent Agent from fabricating position/balance data
- Add strict data truthfulness rules to system prompt (CN + EN)
- Positions MUST come from get_positions tool only
- Balance MUST come from get_balance tool only
- Looking up a stock price != user owns it
- Fix unused variable warnings in hyperliquid trader
2026-03-25 01:05:54 +08:00
shinchan-zhai
e2de4e8d0b feat: US stock pre-market/after-hours data support
- Parse extended hours fields from Sina Finance API (field 21-24)
- Display pre-market/after-hours price, change%, and time in stock quotes
- Update system prompt: stocks have real-time data via search_stock tool
- Remove incorrect 'no real-time stock data' disclaimer
2026-03-25 01:05:54 +08:00
shinchan-zhai
5676ba2e5c feat: dynamic stock search via Sina suggest API
- Add searchStock() using Sina's suggest API (type=11,31,41)
- Supports A-share, HK, and US markets dynamically
- No longer limited to hardcoded knownStocks map
- resolveStockCodeDynamic: tries static map first, then API fallback
- extractStockKeyword: smart keyword extraction from natural language
- New LLM tool 'search_stock': agent can proactively search stocks
- Top 3 search results auto-enriched with real-time quotes
- System prompts updated for both zh/en
2026-03-25 01:05:54 +08:00
shinchan-zhai
0fa8c48b84 feat(agent): LLM tool-calling for auto trade execution
- New agent/tools.go: defines LLM tools (execute_trade, get_positions,
  get_balance, get_market_price)
- thinkAndAct now uses CallWithRequestFull with tool-calling loop
  (max 5 rounds) — LLM autonomously decides when to call tools
- Trade safety: execute_trade creates pending orders requiring user
  confirmation ('确认 trade_xxx' / 'confirm trade_xxx')
- Pending trades expire after 5 minutes
- System prompt updated with tool usage instructions and safety rules
- Both paths work: regex shortcut ('做多 BTC 0.01') and natural
  language ('帮我开一个BTC多单') via LLM tool calling
- Fallback: if tool-calling fails, degrades to plain LLM call
2026-03-25 01:05:54 +08:00
shinchan-zhai
c55800ab68 feat: add multi-turn conversation memory to Agent
- Add chatHistory store (in-memory, per user, last 20 messages)
- Agent now passes full conversation context to LLM via CallWithRequest
- Records both user messages and assistant responses
- Add /clear command to reset conversation history
- Add 'Clear' quick action button in frontend
- Supports natural multi-turn conversations (follow-up questions, context)
2026-03-25 01:05:54 +08:00
shinchan-zhai
2cb8970e23 feat: real-time data for A-shares, HK stocks, and US stocks
Data source: Sina Finance API (free, no key needed)
- A股: sh/sz prefix, GBK→UTF-8, 30+ fields
- 港股: hk prefix, different field layout
- 美股: gb_ prefix, USD prices

Coverage:
- 20+ A-share stocks (拓维信息/贵州茅台/比亚迪/宁德时代...)
- 12 HK stocks (腾讯/阿里/美团/小米/京东...)
- 20 US tickers (AAPL/TSLA/NVDA/MSFT/GOOGL/AMZN...)
- Auto-detect 6-digit A-share codes, 5-digit HK codes
- US ticker symbols recognized (TSLA, AAPL, etc.)

All three markets tested:
- A股 拓维信息: ¥35.57 (-6.71%) 
- 港股 腾讯: HK$510.50 (-0.49%) 
- 美股 TSLA: $367.96 (-3.24%) 
2026-03-25 01:05:54 +08:00
shinchan-zhai
53db1c72ac feat: real-time A-share stock data via Sina Finance API
NOFXi can now fetch REAL stock prices for A-shares.

Data source: Sina Finance hq.sinajs.cn (free, no API key)
- Name, price, open, prev close, high, low, volume, turnover
- Change % calculated from prev close
- GBK → UTF-8 encoding handled

Stock resolution:
- Known stocks: 拓维信息→sz002261, 贵州茅台→sh600519, etc.
- Auto-detect 6-digit codes in user text
- Prefix detection: 6xx→sh, 0xx/3xx→sz

Context injection:
- Stock data auto-appended to LLM context when user mentions a stock
- AI sees REAL price, volume, change % — cannot fabricate

Tested: '拓维信息这只股,10万元,1个月交易计划'
→ Returns ¥35.57 (real price), -6.71% (real change), 53.94亿成交额
→ Strategy based on actual price levels, not hallucinated
2026-03-25 01:05:54 +08:00
shinchan-zhai
3ad71b025d fix: AI no longer fabricates prices for assets without real-time data
System prompt now explicitly:
- Lists which assets have real-time data (crypto) and which don't (stocks/forex)
- FORBIDS fabricating specific prices
- Requires disclosure: 'based on historical knowledge, not live data'
- Allows strategy frameworks but not fake price levels

Tested: 拓维信息 → now says '我没有A股实时数据' upfront, gives
strategy framework without fake prices. Honesty > confidence.
2026-03-25 01:05:54 +08:00
shinchan-zhai
ebd8a9c8f5 fix: bypass SSRF DNS resolver for AI API calls
SSRF protection was blocking AI API calls because Go's custom resolver
couldn't resolve external domains (DNS timeout). curl worked because it
uses the system resolver.

Fix: Agent creates MCP client with standard http.Client (no SSRF filter)
since we control the API URLs.

Tested: '帮我看看拓维信息这只股,我有10万元,帮我制定1个月交易计划'
→ Returns professional A-share analysis with entry/exit strategy in 5.8s
2026-03-25 01:05:54 +08:00
shinchan-zhai
75f271ad65 refactor: delete router.go — LLM is the brain, not regex
DELETED: agent/router.go (regex-based intent routing)

The fundamental architecture was wrong. A real AI Agent doesn't use
pattern matching to understand users. It uses AI.

New flow:
1. User says anything
2. /help and /status → instant response (no AI needed)
3. Setup keywords → onboard flow
4. EVERYTHING else → LLM with full context

The LLM receives:
- System prompt with NOFXi's capabilities and behavior rules
- Real-time market data (auto-detected from mentioned symbols)
- Live trader positions and status
- User's message

The LLM decides what to do. Not regex. Not if-else. The AI.

This is what makes it an Agent, not a chatbot.
2026-03-25 01:05:54 +08:00
shinchan-zhai
d69dad5c1a fix: smart routing + auto AI client from store
1. Complex natural language → AI chat (not regex analyze)
   '拓维信息这个股怎么样帮我写策略' now goes to AI, not broken regex

2. Agent auto-loads AI client from store on startup
   - Scans AIModel configs, creates MCP client from first available
   - No manual injection needed

3. Added start.sh for one-command startup (backend + frontend)

Routing logic:
- /analyze BTC (simple, ≤3 words) → structured analyze
- Complex sentences → AI chat with full context
- This is the key insight: regex can't parse natural language, AI can
2026-03-25 01:05:54 +08:00
shinchan-zhai
58ea77be6b feat: AI-powered analysis for ANY asset (stocks, forex, crypto)
- Crypto: real-time data (market.Get) + AI analysis
- Stocks/Forex: AI answers with its own knowledge (A股/港股/美股/外汇)
- No more 'coming soon' — if AI is configured, it can analyze anything
- Graceful fallback: no AI → guide user to configure
- AI prompt asks for: asset type, fundamentals, trend, key levels, risks
2026-03-25 01:05:54 +08:00
shinchan-zhai
6ab410e50b fix: Agent answers questions first, setup only when asked
Core behavior change:
- Agent NO LONGER auto-prompts setup on first message
- Setup only triggers on explicit: '开始配置' / 'setup' / '绑定交易所'
- Normal questions answered normally, even without trader configured
- AI analysis works without AI model (shows raw data + guidance)
- Stock analysis shows 'coming soon' instead of error

Intent routing improved:
- '你能分析拓维信息吗' → correctly routes to analyze
- Chinese suffixes cleaned (吗/呢/这只股票)
- More natural language patterns matched

Philosophy: Agent should be helpful from minute one.
Configuration is optional, not a gate.
2026-03-25 01:05:54 +08:00
shinchan-zhai
2583ef6aa4 fix: setup flow doesn't hijack normal conversation
- Detects when user sends Chinese text, short text, or text with spaces
  during key-input steps → auto-pauses setup and answers the question
- API key masking fixed (no more garbled display)
- User can resume setup with '开始配置' anytime
2026-03-25 01:05:54 +08:00
shinchan-zhai
9945e4e10d feat: unified NOFXi — one system, one port, one UI
Key changes:
- Agent API routes (/api/agent/*) registered directly on NOFX's :8080 server
- No more separate :8900 port — everything on :8080
- AgentChatPage.tsx added to React frontend
- Agent tab (🤖 Agent) added to navigation bar, set as DEFAULT page
- Branding: NOFX → NOFXi everywhere (title, header, branding.ts, i18n)
- Default landing page is now Agent chat, not competition

This is THE change: there is no more 'NOFX' vs 'NOFXi'.
Users open localhost:8080, they see NOFXi.
Agent chat is the first thing they see.
All other pages (Traders, Dashboard, Strategy, Data) are still there.

One binary. One port. One product. NOFXi.
2026-03-25 01:05:54 +08:00
shinchan-zhai
0f086e5ebc feat: conversational onboarding — setup exchange & AI via chat
Users no longer need Web UI to configure NOFXi. The agent guides them
through setup via natural language:

1. First message → agent detects no traders → shows welcome
2. User says '开始配置' or 'setup'
3. Agent asks: which exchange? (1-7, name, or Chinese name)
4. Agent asks: API Key → API Secret → Passphrase (if needed)
5. Agent asks: which AI model? (DeepSeek/Qwen/GPT/Claude/Skip)
6. Agent asks: AI API Key
7. Agent creates Exchange + AIModel + Trader in NOFX store
8. Done. User can immediately start using /analyze, /positions, etc.

Features:
- Full Chinese/English bilingual flow
- Cancel anytime with '取消' or 'cancel'
- State persisted in SystemConfig (survives restarts)
- Supports all 7 exchanges + 4 AI providers
- OKX/Bitget/KuCoin auto-asks for Passphrase
- API keys stored encrypted via NOFX crypto service
2026-03-25 01:05:54 +08:00
shinchan-zhai
fb456a3537 fix: NOFXi Agent real AI integration + quality improvements
Critical fixes:
1. Agent now uses NOFX's MCP client for AI calls (real models, not placeholder)
   - Gets AI client from first configured trader's MCP config
   - Added AutoTrader.GetMCPClient() export
2. /analyze uses REAL market data (market.Get → EMA/MACD/RSI/BB/OI/funding)
   then sends to AI — no more hallucinated prices
3. AI chat enriches prompts with live market data when user mentions a coin
4. Fallback: if AI unavailable, shows raw formatted market data (still useful)

Router improvements:
- Better natural language detection for Chinese
- '该不该买' '走势' '趋势' '行情' → analyze intent
- '多少钱' '赚了' '亏了' → query intent
- Fewer messages falling through to generic chat

Web UI:
- Endpoints updated to /api/agent/* namespace
- nofxi.html served at agent root (localhost:8900)

Result: AI analysis now shows real BTC price, real RSI, real EMA — not fiction.
2026-03-25 01:05:54 +08:00
shinchan-zhai
f095b6655b feat: NOFXi Agent integrated into NOFX core
This is the key architectural change: NOFXi is no longer a separate
sub-project in nofxi/, but a first-class module in agent/ that sits
on top of NOFX's existing engine.

agent/ package:
- agent.go: Core orchestrator, directly uses NOFX's TraderManager,
  Store, and Market packages. No wrapper/bridge needed.
- brain.go: Proactive intelligence (news scan, market briefs, signal handling)
- sentinel.go: Market anomaly detection (price breakout, volume spike, funding rate)
- scheduler.go: Daily reports, position risk checks
- router.go: Intent routing for natural language (中/英 bilingual)
- i18n.go: Full Chinese/English message catalog
- web.go: Agent REST API on :8900 (chat, klines, ticker)

main.go changes:
- Banner: NOFX → NOFXi
- Agent auto-starts with NOFX (sentinel + brain + scheduler + web)
- Zero breaking changes to existing NOFX functionality

Key difference from old nofxi/:
- Agent reads LIVE data from TraderManager (positions, balances, status)
- Uses market.Get() for full technical indicators (EMA/MACD/RSI/BB)
- No duplicate code — kernel, trader, store all used directly
- Old nofxi/ sub-project will be removed once migration is verified

Architecture:
  NOFX (engine) → kernel + trader + market + store + mcp + telegram
  NOFXi (brain) → agent/ package → uses all of the above
2026-03-25 01:05:54 +08:00