mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-18 09:54:35 +08:00
feat: unify autopilot launch on server preflight with live balance polling
- New shared launch module (web/src/lib/launch): preflight client, model/ exchange resolution, and a single launchAutopilot orchestrator used by both Strategy Studio and the guided launch panel — the two previously duplicated and divergent launch implementations are gone. - Preflight runs BEFORE any strategy mutation, so a failed launch no longer rewrites/activates the strategy as a side effect; readiness and minimums come from the server (live balances) instead of stale client caches. - Guided panel polls preflight every 20s so deposits are detected without manual refresh; step metas show live balances and required minimums; the beginner wallet page polls its balance while the deposit screen is open. - Every failure now routes to a guided fix: hyperliquid-funds gets its own setup anchor (scrolls to the launch panel), start rejections surface the server's preflight reason (including manual restarts from the trader list), and structured error bodies flow through ApiError.errorData. - Terminal dashboard shows a persistent runtime banner when the AI fee wallet runs low/empty or the trader enters safe mode. - Vitest coverage for setup-target routing, readiness helpers, and the launch orchestration order (no side effects before preflight).
This commit is contained in:
@@ -303,6 +303,24 @@ export function TerminalDashboard({
|
||||
navSlot,
|
||||
)}
|
||||
<div className="tm-box" style={{ maxWidth: 1280, margin: '0 auto', border: 'none' }}>
|
||||
{/* runtime health banner — AI fee wallet dry / safe mode would otherwise
|
||||
only be visible in server logs while the bot silently idles */}
|
||||
{!on && status && (status.safe_mode || status.ai_wallet_status === 'empty' || status.ai_wallet_status === 'low') && (
|
||||
<div className="tm-mono" style={{ display: 'flex', gap: 10, alignItems: 'center', margin: '8px 14px 0', padding: '8px 12px', fontSize: 11, border: '1px solid var(--tm-down)', color: 'var(--tm-down)', background: 'rgba(200,60,40,0.06)', flexWrap: 'wrap' }}>
|
||||
<span style={{ fontWeight: 600 }}>
|
||||
{status.ai_wallet_status === 'empty'
|
||||
? 'AI fee wallet is out of USDC — decisions are failing.'
|
||||
: status.ai_wallet_status === 'low'
|
||||
? `AI fee wallet is low (${(status.ai_wallet_balance_usdc ?? 0).toFixed(2)} USDC) — top up soon.`
|
||||
: 'Safe mode: AI failed repeatedly, no new positions are being opened.'}
|
||||
</span>
|
||||
<span style={{ color: 'var(--tm-ink-2)' }}>
|
||||
{status.ai_wallet_status === 'empty' || status.ai_wallet_status === 'low'
|
||||
? 'Deposit Base USDC to the Claw402 wallet, the trader recovers automatically.'
|
||||
: status.safe_mode_reason || ''}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{/* config / identity strip — first row, flows directly under the global nav */}
|
||||
<div className="tm-mono" style={{ display: 'flex', gap: 16, padding: '6px 14px', fontSize: 11, color: 'var(--tm-ink-2)', flexWrap: 'wrap' }}>
|
||||
<span style={{ fontWeight: 500 }}>{selectedTrader?.trader_name ?? 'NOFX'}</span>
|
||||
|
||||
Reference in New Issue
Block a user