feat(ai): add Claude Opus 5 and Sonnet 5 support - #1530
Conversation
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review. 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
Add two new Anthropic models released in 2026: - Claude Opus 4.8 (claude-opus-4-8) — released 2026-05-28, the immediate successor to Opus 4.7. Anthropic kept 4.7's pricing; the per-call estimate here (USD 0.18/call) follows the existing repo convention from PR NoFxAiOS#1510. - Claude Fable 5 (claude-fable-5) — released 2026-06-09, the first publicly available Mythos-class model (a tier above Opus). $10 input / $50 output per 1M tokens per anthropic.com; the per-call estimate (USD 0.36/call) is roughly 2× Opus 4.8's to mirror the 2× token price. Both share 1,000,000 context, 128,000 max output, and the standard Anthropic Messages API. Reference: https://www.anthropic.com/news/claude-fable-5 https://www.anthropic.com/news/claude-opus-4-8 Files changed (5, +25 / -5): - mcp/provider/claude.go `DefaultClaudeModel` bumps to `claude-fable-5` (the newer Mythos-class flagship). - api/handler_ai_model.go the `claude` row in `supportedModels` exposes `claude-fable-5` so the UI shows the same default the runtime picks up. - mcp/payment/claw402.go `claw402ModelEndpoints` adds `claude-opus-4-8` and `claude-fable-5` x402 paths; the legacy `claude-opus` alias is kept. - store/ai_charge.go `modelPrices` gains `claude-opus-4-8 = 0.18` and `claude-fable-5 = 0.36` with comments citing the anthropic.com pricing sheet. - web/src/components/trader/model-constants.ts Both tiers enter `CLAW402_MODELS` (Fable 5 with the dragon icon \u{1F409}) and `BLOCKRUN_MODELS`; `AI_PROVIDER_CONFIG`. `claude.defaultModel` -> `claude-fable-5`. Backward compatible — existing `claude-opus`, `claude-opus-4-6` entries and prices remain unchanged and selectable. Default model policy: this PR is the single place where the Anthropic default changes (to Fable 5). All `WithModel(...)` override callers continue to pick any model they want via the existing hook.
548ed55 to
a8597a7
Compare
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
Operator choice to add aggression while keeping the hold-for-big-moves design intact: - Leverage 5x -> 10x: a wide -5% stop is now -50% of margin — still survivable, not an instant liquidation (that needed 20x). - Per-position notional 2.5x -> 5x equity; 2 positions = 10x total account notional (full margin at 10x, ~10% liquidation cushion). - Stops/targets, throttle, min-hold and noise-band settings unchanged: same wide (-5% / +10-12%) exits, doubled exposure. Live strategy in data/data.db updated to match (lev=10, ratio=5.0).
…t-privilege permissions pr-checks-comment.yml runs in the privileged workflow_run context with a write token while consuming artifacts produced by the untrusted PR workflow. Seven spots template-interpolated that untrusted data (and the fork-controlled head branch name) directly into github-script source — a crafted artifact could escape the string literal and run arbitrary JS with the privileged token (CodeQL actions/code-injection, critical). - All untrusted values now flow through env vars and process.env; the PR number is parsed and validated before use - test.yml / docker-build.yml gain workflow-level 'permissions: contents: read' (CodeQL actions/missing-workflow-permissions); publish jobs keep their job-level packages:write
Replay recorded AI decisions from decision_records under alternative risk-control and throttle parameters, then search the 15-dim space with Optuna multivariate TPE. - extract.py: parse decision cycles, intents (incl. throttled ones), 15m OHLCV and per-cycle prices out of input prompts into CSVs - simulate.py: replay engine mirroring auto_trader_throttle.go semantics (margin-based PnL%% thresholds, intra-candle SL/TP trigger orders, opens/hour + reentry + margin gates); live-config replay reproduces the real account curve (-83%% sim vs -85%% actual) - search.py: TPE search (train/holdout split) + baselines + importances Findings: train-window optima do not survive holdout (overfit); only 2/800 trials are positive across all 3 time folds. Dominant lever is min_confidence (importance 0.79) — the edge problem is decision quality, not risk parameters.
Live decomposition of the 2026-07-23 drawdown (equity 62.6 -> 31.1 in one day, 43 fills, avg hold <1h despite a 4h min hold): both exit guards compared thresholds meant as price moves against leverage-multiplied margin PnL%, so raising leverage 5x -> 10x silently halved every trigger distance: - throttle bypass: -5% 'stop' unlocked AI closes at a -0.5% price wiggle (ETH -0.5%/44min, AAVE -0.9%/45min, MU -2.4%/14min all sailed through) - drawdown monitor: 'profit > 5%' armed at +0.5% price, then market-closed winners on a 40% giveback (SNDK +0.6%/35min, NVDA +0.3%/37min) — every winner strangled at breakeven while losers realized fast Fix: evaluate both guards on price-basis PnL (margin PnL% / leverage). Throttle thresholds keep their documented price meaning at any leverage; the drawdown monitor now arms only after a real +5% price move. Peak-PnL cache stays margin-basis for prompt display consistency. Replay simulator updated to the same price-basis semantics.
The trading account could only be funded outside NOFX: no way to move
spot ('main wallet') USDC into the perp trading account, and no deposit
address/QR shown anywhere.
- API: /hyperliquid/account now also returns spot USDC (total/available)
alongside the perp summary; /hyperliquid/submit-exchange accepts a
validated usdClassTransfer action (positive plain amount, boolean
toPerp, Mainnet chain) relayed like the existing approval actions
- Web: new HyperliquidFundsPanel in the exchange config modal with a
deposit tab (wallet address QR + Arbitrum/spot routing notes) and a
transfer tab (spot<->perp, signed by the user's own wallet via EIP-712
UsdClassTransfer — user-signed actions derive the account from the
signature, so the agent key NOFX holds cannot and does not move funds)
- Shared EIP-712/provider helpers extracted from HyperliquidWalletConnect
into lib/hyperliquidWallet.ts
…ding copy The deposit tab claimed USDC sent to the user's own address on Arbitrum is auto-credited to the perp account. Wrong: sending to your own address only funds the wallet. Hyperliquid's canonical deposit is native USDC on Arbitrum One sent to the validator-controlled Bridge2 contract (0x2Df1c51E09aECF9cacB7bc98cB1742757f163dF7), which credits the SENDER's account (min 5 USDC, ~1 min) — verified against Arbiscan and HL docs. - Deposit tab now explains the two-step flow (fund wallet -> bridge in) and adds a one-click deposit: switches the wallet to Arbitrum One and sends an ERC-20 transfer of native USDC to Bridge2 - Enforces the connected wallet == configured main wallet (the bridge credits the sender, so any other wallet would fund the wrong account) - Blocks sub-minimum amounts client-side (they would be lost)
The deposit tab told users to deposit wallet USDC but never showed how much the wallet held — the 328 USDC sitting on Arbitrum was invisible, so the deposit flow looked like there was nothing to deposit. - Third balance card 'Wallet (Arbitrum)': native USDC balance + ETH gas (red warning when gas is zero), fetched directly from the public Arbitrum RPC (balanceOf + eth_getBalance), refreshed with the panel - 'Depositable' amount shown next to the bridge form + Max button - Client-side check: deposit amount cannot exceed the wallet balance
…and transfer tab Per HL's account-abstraction-modes docs, unified accounts (the default and HL's recommendation) hold ONE USDC balance that collateralizes spot, validator perps and HIP-3 perps — there is no spot/perp split and no class transfer. The panel was presenting manual-mode concepts (spot vs perp cards, a spot->perp transfer tab) to unified users: confusing and wrong. - unifiedAccount prop (from the exchange's hyperliquid_unified_account, default true): hides the transfer tab and shows a single 'Hyperliquid account' card — total / tradable / margin in use, derived from the spot balance and its hold - Manual-mode accounts keep the split cards and transfer tab - Deposit copy simplified: funds are tradable right after the bridge credit, no extra step
Per-position one-click close already existed (Action column, with confirm), but flattening the whole book took one confirm per position. Adds a 'Close All' button next to the position count: single confirm, then closes every position sequentially (parallel closes can race on exchange nonces/rate limits), refreshes via SWR and reports a partial- failure count. zh/en/id translations included.
…live' panel The one-click close only existed on the legacy dashboard's positions table; the terminal dashboard the user actually sees had a read-only positions panel. Adds a per-row 'close' button (confirm -> market close via the existing /close-position API) and a 'close all' button in the panel header (single confirm, sequential closes to avoid nonce races, partial-failure report). Hidden in demo mode and when no trader is selected; SWR keys refresh positions and account after closing.
The anti-churn exit gates (min hold, noise-close window, re-entry cooldown, bypass and noise-band thresholds) were hardcoded constants in auto_trader_throttle.go — every flat-ish position was forced to hold 8h+ and changing the pacing meant a code change and redeploy. - RiskControlConfig gains 7 exit-gate fields (minutes / signed price-%), zero = built-in default; accessor methods centralize fallbacks and are hot-reloaded from the DB like the rest of the strategy config - Throttle reads the gates from the strategy; prompt hold/exit guidance is now rendered from the same values so the AI is told exactly what the code will enforce - Defaults softened: min hold 4h -> 1.5h, noise window 8h -> 3h, re-entry 3h -> 1.5h, bypasses -5/+12 -> -3/+8, noise band -4..+6 -> -2..+3 (price-basis). A +-2-3% move is 15-20x round-trip fees — no longer 'noise' worth locking - Strategy Studio gets an 'exit pacing' row (min hold / flat-close window / re-entry cooldown); thresholds editable via strategy JSON - Live strategy updated in data/data.db with the softened values
… values Operator call: no per-strategy configurability for exit pacing — it added config fields, UI and plumbing nobody wanted. Back to plain constants in auto_trader_throttle.go, now set to the replay-validated values instead of the original guesses (4154 cycles, 3-fold robust search over only the 7 exit params, everything else fixed at the live config): - min hold 90m, noise-close window 3h, noise band -2%..+3%, bypasses -3%/+8% (all inside the searched top-20 ranges) - re-entry cooldown 4h — the one clear signal: top-20 configs cluster tightly at 3.8-4.0h; re-entering a just-closed symbol was a consistent loss source Removes the 7 RiskControlConfig fields + accessors, the Strategy Studio 'exit pacing' row, the frontend type fields, and the fields from stored strategy configs in data/data.db. Prompt guidance is static text again, matching the constants.
Clears all 7 critical Dependabot alerts (SSH subsystem: auth bypass via unenforced @Revoked status, VerifiedPublicKeyCallback permission skip, key-constraint enforcement gaps, server deadlock and infinite-loop DoS). Transitive dependency only — nothing in NOFX imports x/crypto directly.
- react-router/react-router-dom 7.17.0 -> 7.18.1 (route-matching DoS, GHSA-chx6-hx7r-mcp5) - axios 1.16.1 -> 1.18.1 (inherited-proxy leak, GHSA-gcfj-64vw-6mp9) - postcss 8.5.15 -> 8.5.23 (source-map path traversal, GHSA-r28c-9q8g-f849) - brace-expansion pinned to 1.1.16 / 2.1.2 across all nested copies via overrides (exponential-expansion DoS, GHSA-3jxr-9vmj-r5cp) Remaining GHSA-qwww-vcr4-c8h2 (react-router RSC-mode CSRF) is dismissed on GitHub as not-used: the app is a Vite SPA, RSC mode is never enabled, and the fix requires a react-router v8 major upgrade.
df6548b to
d9edeb4
Compare
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review. 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
# Conflicts: # api/handler_ai_model.go # api/handler_hyperliquid_wallet_test.go # mcp/payment/claw402.go # store/ai_charge.go # web/src/components/common/HyperliquidFundsPanel.tsx # web/src/components/common/HyperliquidWalletConnect.tsx # web/src/components/trader/model-constants.ts # web/src/lib/hyperliquidWallet.ts
🤖 Advisory Check ResultsThese are advisory checks to help improve code quality. They won't block your PR from being merged. 📋 PR InformationTitle Format: ✅ Good - Follows Conventional Commits 🔧 Backend ChecksGo Formatting: Files needing formattingGo Vet: ✅ Good Fix locally: go fmt ./... # Format code
go vet ./... # Check for issues
go test ./... # Run tests⚛️ Frontend ChecksBuild & Type Check: ✅ Success Fix locally: cd web
npm run build # Test build (includes type checking)📖 ResourcesQuestions? Feel free to ask in the comments! 🙏 These checks are advisory and won't block your PR from being merged. This comment is automatically generated from pr-checks-run.yml. |
Summary
claude-opus-5andclaude-sonnet-5.Relationship to #1527
This PR is based on and depends on #1527, which introduces Claude Opus 4.8 and Claude Fable 5 support. Once #1527 is merged, this PR adds the remaining current Claude 5 models without changing the existing Anthropic integration architecture.
Change Type
Scope
Official References
claude-opus-5claude-sonnet-5The per-call values follow the repository’s existing approximate call-pricing convention.
Testing
go test ./api ./mcp/payment ./mcp/provider ./storego vet ./api ./mcp/payment ./mcp/provider ./storecd web && npm run test— 128 tests passedcd web && npm run buildSecurity Impact
Compatibility
claude-opus-5.Scope Boundary
This PR does not change Anthropic authentication, request/response wire formats, trading behavior, strategy logic, or database schema.
Depends on #1527.