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
This commit is contained in:
shinchan-zhai
2026-03-23 14:01:11 +08:00
parent 9bb1ab8da3
commit d6dafd830e
12 changed files with 135 additions and 34 deletions

View File

@@ -21,27 +21,23 @@ const SYMBOL_ICONS: Record<string, string> = {
export function MarketTicker() {
const [tickers, setTickers] = useState<Record<string, TickerData>>({})
const [loading, setLoading] = useState(true)
const [, setRefreshing] = useState(false)
const fetchTickers = async () => {
try {
const results = await Promise.all(
SYMBOLS.map(async (symbol) => {
const res = await fetch(`/api/agent/ticker?symbol=${symbol}`)
const data = await res.json()
return { symbol, ...data }
})
)
// Batch fetch: single API call for all symbols
const res = await fetch(`/api/agent/tickers?symbols=${SYMBOLS.join(',')}`)
const data = await res.json()
const map: Record<string, TickerData> = {}
results.forEach((r) => {
if (r.lastPrice) map[r.symbol] = r
})
if (Array.isArray(data)) {
data.forEach((r: TickerData) => {
if (r.lastPrice && r.symbol) map[r.symbol] = r
})
}
setTickers(map)
} catch {
// ignore
// ignore — will retry on next interval
} finally {
setLoading(false)
setRefreshing(false)
}
}

View File

@@ -75,7 +75,7 @@ export function AuthProvider({ children }: { children: React.ReactNode }) {
// Listen for unauthorized events from httpClient (401 responses)
useEffect(() => {
const handleUnauthorized = () => {
console.log('Unauthorized event received - clearing auth state')
console.warn('Unauthorized event received - clearing auth state')
// Clear auth state when 401 is detected
setUser(null)
setToken(null)

View File

@@ -272,7 +272,7 @@ export function AgentChatPage() {
<div
style={{
display: 'flex',
height: 'calc(100vh - 64px)',
height: 'calc(100dvh - 64px)',
background: '#09090b',
overflow: 'hidden',
}}