Commit Graph

1096 Commits

Author SHA1 Message Date
shinchan-zhai
efdf4856c5 docs: update nofxi-tasks.md with Alpaca bug fixes 2026-03-25 01:05:54 +08:00
shinchan-zhai
33b725ca14 fix: Alpaca integration bugs — field mapping, market hours, stock symbol handling
- Fix critical bug: Alpaca GetBalance returns wrong field names (total_equity
  vs totalEquity) — auto_trader was getting 0 equity, breaking all decisions
- Fix critical bug: Alpaca GetPositions missing positionAmt/unRealizedProfit
  fields — positions invisible to trading AI
- Fix CancelAllOrders: was nuking ALL orders globally, now filters by symbol
- Implement GetClosedPnL: was returning nil, now returns filled sell orders
- Add IsMarketOpen: checks Alpaca clock endpoint for market hours
- Add market hours check in trading loop: skip cycles when US market closed
  (saves LLM tokens and prevents failed orders)
- Fix parseTradeCommand: 'BUY AAPL 10' no longer becomes 'AAPLUSDT'
- Fix toolGetMarketPrice: route stock symbols to Alpaca, crypto to others
- Add exchange field to toolGetPositions output for multi-exchange clarity
2026-03-25 01:05:54 +08:00
shinchan-zhai
7e77b92fd0 feat: Alpaca US stock trader integration (Tasks 8-11)
- trader/alpaca/: Full Trader interface implementation for Alpaca
  - Paper/Live trading support (market orders, stop/limit)
  - GetBalance, GetPositions, GetMarketPrice via Alpaca API
  - Fractional share support (4 decimal places)
  - Commission-free trading

- Agent trade routing: stock symbols (AAPL, TSLA) → Alpaca
  - isStockSymbol() heuristic to distinguish crypto vs stock
  - execute_trade tool updated for stock buy/sell semantics
  - get_market_price works for both crypto and stocks

- TraderManager + API: Alpaca registered as exchange type
  - Factory case in auto_trader.go
  - Config mapping in trader_manager.go
  - Temp trader creation in handler_trader.go for balance query

- Frontend: PositionsPanel distinguishes stock vs crypto
  - US flag emoji for stock positions
  - Dollar prefix for stock PnL/prices
  - 'Shares' label instead of 'Qty' for stocks

- System prompts updated for stock trading capabilities
2026-03-25 01:05:54 +08:00
shinchan-zhai
abb43c8c68 fix: division-by-zero guard, rate-limit wallet endpoints, safer JSON parse, Lighter HTTP checks
- Guard GridCount-1 division by zero in grid spacing calculation (both grid.go and grid_levels.go)
- Rate-limit /wallet/validate and /wallet/generate endpoints (prevent DoS on key generation)
- Wrap JSON.parse(localStorage) in try-catch in AuthContext (corrupted data → graceful re-login)
- Wrap handleJSONResponse JSON.parse in try-catch with descriptive error
- Add HTTP status code checks for Lighter GetActiveOrders and sendTx
- Replace deprecated strings.Title with cases.Title (golang.org/x/text)
- Reuse HTTP client in checkClaw402Health (was creating new client per call)
2026-03-25 01:05:54 +08:00
shinchan-zhai
c014724896 fix: context propagation in LLM calls, SSE error handling, security hardening
- Propagate request context through MCP client (Request.Ctx field)
  — Client disconnects now cancel in-flight LLM API calls (both streaming and non-streaming)
  — Prevents wasted LLM tokens when user navigates away mid-response
- proxyBinance: use http.NewRequestWithContext for context-aware upstream calls
  — Client disconnects cancel Binance proxy requests
  — Distinguishes client cancellation from upstream failures
- Fix SSE parse bug in AgentChatPage: catch block was swallowing error events
  — throw new Error(data) for 'error' events was caught by the same try/catch
  — Now parse JSON separately, then handle events outside try/catch
- Add io.LimitReader to Hyperliquid coins.go JSON decoder (4MB limit)
- Use safe.ReadAllLimited in batch ticker handler for consistency
- Sanitize URL validation error in handler_ai_model.go (was leaking raw error)
- Cache agent tool definitions (built once, reused per message)
- Sort trade history by exit time for consistent ordering
2026-03-25 01:05:54 +08:00
shinchan-zhai
d6dafd830e fix: SSE streaming for no-tool path, batch ticker API, security & cleanup
- Fix thinkAndActStream: emit delta event for non-tool responses (was silent)
- Add fallback to streaming on first LLM call failure
- Add batch ticker endpoint /api/agent/tickers (3 API calls → 1)
- Update MarketTicker to use batch endpoint, remove unused state
- Warn loudly when JWT_SECRET uses default value
- Fix 华为 mapping (was incorrectly mapped to Tencent)
- Replace ioutil.ReadAll with safe.ReadAllLimited in nofxos client
- Remove unused variable in hyperliquid trader_account
- Wrap CoinAnk WS readers with safe.GoNamed for panic recovery
- Use 100dvh for mobile viewport in AgentChatPage
- console.log → console.warn for auth events
2026-03-25 01:05:54 +08:00
shinchan-zhai
9bb1ab8da3 feat: real SSE streaming for agent chat + data cleanup on startup
SSE Streaming:
- Add POST /api/agent/chat/stream endpoint with real SSE streaming
- Agent.HandleMessageStream() streams final LLM response via onEvent callback
- Tool-calling rounds use non-streaming; tool status sent as 'tool' events
- Frontend uses ReadableStream API instead of fake word-by-word setTimeout
- SSE events: tool (tool execution), delta (text chunk), done (complete), error

Data Maintenance:
- Add cleanupOldData() on server startup (decisions >90d, equity >180d)
- Add CleanOldRecords to DecisionStore and EquityStore
- Add store-level logger for cleanup operations

Exchange Traders:
- Add GetAccountInfo() to Bitget, Bybit, Indodax, KuCoin, Lighter, OKX traders
- Remove unused imports in Aster/Lighter traders
2026-03-25 01:05:54 +08:00
shinchan-zhai
9682d3690d docs: stock trading design + add Alpaca/LongPort tasks to self-drive queue
- Comprehensive design doc: US/HK/A-share trading API comparison
- Phase 1: Alpaca (US stocks) - paper trading first
- Phase 2: LongPort (HK stocks)
- Phase 3: A-share via Stock Connect
- 10 new [PENDING] tasks for self-drive cron
2026-03-25 01:05:54 +08:00
shinchan-zhai
c58e782b2e docs: update nofxi-tasks.md — record 12:52 batch 2026-03-25 01:05:54 +08:00
shinchan-zhai
6e10d84043 fix: graceful HTTP shutdown, add ErrorBoundary, fix chart responsive height
- main.go: call server.Shutdown() on SIGTERM/SIGINT to drain in-flight requests
- Add React ErrorBoundary component (catches render crashes, shows retry UI)
- Wrap main content area and settings page with ErrorBoundary
- Fix ChartTabs.tsx: replace runtime window.innerWidth check with Tailwind responsive class (h-[500px] md:h-[600px])
- Restarted backend with latest build (health endpoint now returns proper timestamp)
2026-03-25 01:05:54 +08:00
shinchan-zhai
85b9d1dc4e docs: update nofxi-tasks.md — record 12:37 batch 2026-03-25 01:05:54 +08:00
shinchan-zhai
8a7ac8719a feat: dynamic crypto detection, trade history tool, fix 9 ticker leaks
- Agent gatherContext: expand from 10 hardcoded symbols to 38+ known symbols
  plus dynamic XXXUSDT pattern extraction (caps at 5 to avoid slow context)
- Add get_trade_history tool: LLM can now query closed trades with PnL summary
  (win rate, total PnL, recent N trades across all traders)
- Fix ticker.Stop() leak in ALL 9 exchange order_sync goroutines:
  OKX, Hyperliquid, Aster, Bybit, KuCoin, Gate, Bitget, Lighter, Binance
  — tickers were never stopped when traders were stopped, leaking goroutines
2026-03-25 01:05:54 +08:00
shinchan-zhai
14aaa87117 docs: update nofxi-tasks.md — record 12:22 batch 2026-03-25 01:05:54 +08:00
shinchan-zhai
3c39d1efbe fix: consistent safe type helpers in auto_trader, log emergency exit errors
- Replace all raw pos["key"].(type) assertions with posFloat64/posString/posInt64 helpers
  across auto_trader_decision, auto_trader_grid, auto_trader_grid_orders,
  auto_trader_grid_regime, auto_trader_loop, auto_trader_orders, auto_trader_risk
- Add posInt64 helper for int64 extraction (createdTime etc)
- Fix emergencyExit: log CloseLong/CloseShort errors instead of silently dropping
- Fix emergencyExit: log GetPositions error on failure
- Upgrade closeAllPositions log level from Infof to Warnf for close failures
- Zero raw type assertions remaining in auto_trader_* files
2026-03-25 01:05:54 +08:00
shinchan-zhai
ed9230d38b fix: toFloat handles json.Number, CORS credentials+wildcard bug, strategy config error handling
- agent/agent.go: toFloat() now handles json.Number and int32 types to prevent silent data loss
- api/server.go: CORS fix — echo specific origin instead of '*' when credentials are enabled (browsers reject Allow-Credentials with wildcard)
- api/strategy.go: all 4 json.Unmarshal calls now check errors and return 'config_error' field instead of silently serving zero-value configs
- store/decision.go: explicitly mark best-effort unmarshal with _ = assignment for clarity
2026-03-25 01:05:54 +08:00
shinchan-zhai
6987d7e886 docs: update nofxi-tasks.md with panic prevention work 2026-03-25 01:05:54 +08:00
shinchan-zhai
6911bc3e2b fix: prevent panics from unsafe type assertions in trading code + add request body limit
Security & Reliability:
- Add requestBodyLimitMiddleware (1MB) to prevent OOM from oversized API payloads
- Fix defer resp.Body.Close() inside loop in getPublicIPFromAPI (connection leak)
- Add posFloat64/posString safe helpers for position map access

Panic Prevention (critical for trading):
- Convert 30+ unsafe type assertions (pos["key"].(type)) to safe comma-ok
  pattern across all exchange traders: OKX, Hyperliquid, Aster, Bybit,
  KuCoin, Gate, Bitget, Binance
- Fix auto_trader_risk.go: drawdown monitor could panic and silently stop
  monitoring, leaving positions unprotected
- Fix auto_trader_decision.go & auto_trader_loop.go: core trading loop
  position parsing now crash-proof
- All trader/ code now has zero unsafe type assertions

Frontend:
- Fix config.ts: rejected promise cached forever on network error (never retries)
2026-03-25 01:05:54 +08:00
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
7df11f65ff docs: update nofxi-tasks.md — record 11:22 batch 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
9235d9cd24 docs: update nofxi-tasks.md — record 10:52 batch progress 2026-03-25 01:05:54 +08:00
shinchan-zhai
b94b64a305 robustness: add HTTP status code checks to market data & provider APIs
- market/api_client.go: check StatusCode for exchangeInfo, klines, price
  endpoints + add truncateBody helper for safe error messages
- market/data.go: check StatusCode for openInterest and premiumIndex
- provider/coinank: check StatusCode for GET and POST requests
- provider/twelvedata: check StatusCode for time series and quote APIs
- Prevents confusing JSON unmarshal errors when APIs return 429/500/etc
2026-03-25 01:05:54 +08:00
shinchan-zhai
a5ac1b300b perf: reuse shared HTTP client in Hyperliquid trader
Previously each direct API call (orders, sync, account) created a new
http.Client, preventing TCP/TLS connection reuse. Now all calls share
a single client on the HyperliquidTrader struct (30s timeout).
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
82a35a8cae security: sanitize internal error messages in API responses
- handler_trader.go: remove loadErr.Error() from 500 responses (2 instances)
- handler_ai_cost.go: replace err.Error() with generic message, add logging
- Internal errors now logged server-side, not exposed to clients
2026-03-25 01:05:54 +08:00
shinchan-zhai
9246cb7f00 security: upgrade vulnerable deps + refactor AgentChatPage
Dependencies upgraded:
- go-ethereum v1.16.7 → v1.16.8 (fixes GO-2026-4508 DoS + GO-2026-4314/4315 p2p vulns)
- golang-jwt/jwt v5.2.0 → v5.2.2 (fixes GO-2025-3553 header parsing memory alloc)
- quic-go v0.54.0 → v0.57.0 (fixes GO-2025-4233 HTTP/3 QPACK DoS)

Frontend refactor:
- Extract WelcomeScreen component (welcome state + suggestion cards)
- Extract ChatMessages component (message list with avatars + streaming)
- Extract ChatInput component (textarea + send button + Cmd+K shortcut)
- AgentChatPage: 825 → 480 lines

Note: 3 stdlib vulns (GO-2026-4599/4600/4601) require Go 1.26.1 upgrade
2026-03-25 01:05:54 +08:00
shinchan-zhai
f1394d779a docs: update nofxi-tasks.md — record complete panic recovery coverage 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
e671268763 docs: update nofxi-tasks.md — record 10:07 batch progress 2026-03-25 01:05:54 +08:00
shinchan-zhai
7c668cd7ef security+reliability: remove public decrypt endpoint, add panic recovery for goroutines
Security:
- Remove /api/crypto/decrypt from public routes. The endpoint allowed
  anyone to decrypt ciphertext without authentication. Internal callers
  (exchange/model handlers) use the service directly and are behind auth.

Reliability:
- Add safe.Go / safe.GoNamed panic recovery wrapper (safe/go.go).
  Previously 31 goroutines had zero recover() calls — a single panic
  in any trader goroutine would crash the entire process.
- Apply safe.GoNamed to all trader launch paths:
  - StartAll, RestoreRunning, LoadSingleTrader auto-start
  - API handler start/restart endpoints
- Panics are now logged with full stack traces instead of crashing.
2026-03-25 01:05:54 +08:00
shinchan-zhai
25e470dfbb refactor: propagate request context in kline handlers, extract MessageRenderer component
- handler_klines.go: pass c.Request.Context() to all external API calls
  instead of context.Background(). Client disconnects now cancel upstream
  requests to CoinAnk, Alpaca, TwelveData, Hyperliquid.
- Extract renderMessageContent + renderInline into
  components/agent/MessageRenderer.tsx (187 lines).
  AgentChatPage.tsx reduced from 1009 → 825 lines.
2026-03-25 01:05:54 +08:00
shinchan-zhai
edeac8a0d2 docs: update nofxi-tasks.md — mark completed, clean false positives 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
2b969ee668 security: sanitize markdown link URLs to prevent javascript: XSS
Only allow http/https URLs in rendered markdown links. Replace any
non-http(s) URL with '#' to prevent potential javascript: URI attacks.
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
84758e2942 chore: remove ~100 debug console.log statements from frontend
Cleaned up verbose debug logging left from development:
- AdvancedChart.tsx: removed ~50 debug logs (time parsing, order fetching, marker creation)
- ChartWithOrders.tsx: removed debug logs and unused klineMinTime/klineMaxTime variables
- ChartWithOrdersSimple.tsx: removed data loading debug logs
- ChartTabs.tsx: removed render/selection debug logs
- ComparisonChart.tsx: removed equity history debug logs
- AITradersPage.tsx: removed 🔥 DEBUG logs from handleSaveEditTrader
- App.tsx: removed mount debug log

Kept legitimate console.error/console.warn for actual error handling.
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
9264f1af82 fix: root route shows Agent page instead of LandingPage
- / now defaults to AgentChatPage (NOFXi's main interface)
- Agent page accessible without login
- LandingPage only shown at /landing or for non-agent pages when not logged in
2026-03-25 01:05:54 +08:00
shinchan-zhai
2c020d3dc7 feat(ui): final polish — ChatGPT-style welcome screen, enhanced markdown, typing indicator
- Welcome state: centered greeting with 4 suggestion cards (ChatGPT style grid)
- Enhanced markdown: headers, numbered/bullet lists, links, italic, HR support
- Typing indicator: bouncing dots animation while waiting for response
- Refined dark theme: subtle rgba borders, backdrop blur, better contrast hierarchy
- Improved sidebar: slimmer 280px, glass morphism effect, smoother hover states
- MarketTicker: crypto icons (₿/Ξ/◎), skeleton loading, monospace prices
- Input area: ArrowUp send icon, ⌘K shortcut hint, focus ring glow
- Keyboard shortcuts: Cmd+K focus input, Esc close mobile sidebar
- Custom scrollbar styling, hidden scrollbar for quick actions bar
- Removed initial bot message in favor of interactive welcome state
2026-03-25 01:05:54 +08:00
shinchan-zhai
afa73790c7 chore: remove legacy nofxi/ subdirectory
All functionality has been migrated to the top-level agent/ package.
The old nofxi/ code was fully self-contained with no external references.
Integration plan doc preserved in docs/nofx-integration-plan.md.

Removed 35 files, ~4400 lines of dead code.
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
4cba7edd19 feat: wire NOFXi Agent into Telegram bot
- Add NOFXiAgent interface and SetNOFXiAgent() in telegram/bot.go
- Telegram messages now route through the unified agent.Agent
  instead of the legacy telegram/agent package
- Language hint injected from Telegram config for proper i18n
- Legacy telegram/agent path preserved as fallback
- Agent created before Telegram bot starts in main.go
- Build verified, API tested
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
a21479a358 feat: redesign AgentChatPage - Agent-centric UI with side panels
- Rewrite AgentChatPage as primary interface with Perplexity-style layout
- Add right sidebar with Market Ticker, Positions, and Trader Status panels
- Sidebar is collapsible and responsive (auto-hides on mobile)
- Each sidebar section independently collapsible
- Chat area: centered 720px max-width with smooth streaming effect
- Simple markdown rendering (bold, code blocks, inline code)
- Quick action chips redesigned as pill buttons with hover effects
- Input upgraded to auto-resizing textarea
- New components: MarketTicker, PositionsPanel, TraderStatusPanel
- Dark theme consistent with NOFXi brand colors
- Real-time data via SWR for positions and trader status
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