mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-16 09:11:03 +08:00
feat(agent): surface the AI500 index board in chat, tools, and sidebar
- provider/nofxos: GetAI500ListCached — 5min TTL cache with stale fallback on upstream failure; ResolveClient routes through the claw402 gateway when a wallet key is configured (user's claw402 model key -> CLAW402_WALLET_KEY env -> direct nofxos) - new GET /api/ai500 endpoint serving the score-sorted board - new get_ai500_list agent tool + prompt rule: when the user wants coin picks or creates a strategy without naming coins, consult AI500's high-scoring entries by default - web: AI500 sidebar panel (rank, score badge, gain since entry, 5min auto-refresh); clicking an entry asks the agent to analyze it
This commit is contained in:
@@ -8,6 +8,7 @@ import {
|
||||
Bot,
|
||||
Bookmark,
|
||||
Zap,
|
||||
Sparkles,
|
||||
ChevronDown,
|
||||
ChevronRight,
|
||||
} from 'lucide-react'
|
||||
@@ -21,6 +22,8 @@ import { ChatMessages } from '../components/agent/ChatMessages'
|
||||
import { ChatInput, type ChatInputHandle } from '../components/agent/ChatInput'
|
||||
import { UserPreferencesPanel } from '../components/agent/UserPreferencesPanel'
|
||||
import { HyperliquidSymbolsPanel } from '../components/agent/HyperliquidSymbolsPanel'
|
||||
import { AI500Panel } from '../components/agent/AI500Panel'
|
||||
import type { AI500Coin } from '../lib/api/data'
|
||||
import { createHyperliquidQuickTrader } from '../lib/hyperliquidQuickTrade'
|
||||
import { useAgentChatStore } from '../stores/agentChatStore'
|
||||
import type { AgentMessage as Message, AgentStep } from '../types/agent'
|
||||
@@ -467,6 +470,7 @@ export function AgentChatPage() {
|
||||
// Sidebar section collapse state
|
||||
const [sections, setSections] = useState({
|
||||
market: true,
|
||||
ai500: true,
|
||||
positions: true,
|
||||
traders: false,
|
||||
preferences: true,
|
||||
@@ -582,6 +586,15 @@ export function AgentChatPage() {
|
||||
chatInputRef.current?.focus()
|
||||
}
|
||||
|
||||
const analyzeAI500Symbol = (coin: AI500Coin) => {
|
||||
const display = coin.pair.replace(/USDT$/i, '')
|
||||
const text =
|
||||
language === 'zh'
|
||||
? `分析一下 AI500 里的 ${display}(当前 AI 评分 ${coin.score.toFixed(1)}),给出趋势判断和交易建议`
|
||||
: `Analyze ${display} from the AI500 index (current AI score ${coin.score.toFixed(1)}) and give me a trend read plus a trading suggestion`
|
||||
void send(text)
|
||||
}
|
||||
|
||||
const tradeHyperliquidSymbol = async (symbol: { symbol: string; display?: string; category?: string }) => {
|
||||
const label = symbol.display || symbol.symbol
|
||||
const time = new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })
|
||||
@@ -720,6 +733,18 @@ export function AgentChatPage() {
|
||||
title: language === 'zh' ? '市场行情' : 'Market',
|
||||
component: <MarketTicker />,
|
||||
},
|
||||
{
|
||||
key: 'ai500' as const,
|
||||
icon: <Sparkles size={14} />,
|
||||
title: language === 'zh' ? 'AI500 精选' : 'AI500 Picks',
|
||||
component: (
|
||||
<AI500Panel
|
||||
language={language}
|
||||
disabled={loading}
|
||||
onAnalyzeSymbol={analyzeAI500Symbol}
|
||||
/>
|
||||
),
|
||||
},
|
||||
{
|
||||
key: 'hyperliquid' as const,
|
||||
icon: <Zap size={14} />,
|
||||
|
||||
Reference in New Issue
Block a user