Skip to content

feat(ai): add Claude Opus 5 and Sonnet 5 support - #1530

Open
Hansen1018 wants to merge 78 commits into
NoFxAiOS:devfrom
Hansen1018:feat/add-claude-5
Open

feat(ai): add Claude Opus 5 and Sonnet 5 support#1530
Hansen1018 wants to merge 78 commits into
NoFxAiOS:devfrom
Hansen1018:feat/add-claude-5

Conversation

@Hansen1018

@Hansen1018 Hansen1018 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Add official Anthropic model IDs claude-opus-5 and claude-sonnet-5.
  • Expose both models in the Claw402 and BlockRun model selectors.
  • Add Anthropic Messages API routing for both models through Claw402.
  • Add per-call pricing estimates based on the official Anthropic pricing tiers.
  • Make Claude Opus 5 the default Claude model across backend and frontend configuration.
  • Preserve existing Claude Opus 4.8 and Claude Fable 5 support.

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

  • Feature
  • Bug fix
  • Refactoring
  • Docs
  • Security fix
  • Chore / infra

Scope

  • MCP / AI clients
  • API / server
  • Web UI / frontend
  • Trading engine / strategies
  • Telegram bot / agent
  • Config / deployment
  • CI/CD / infra

Official References

Model Official model ID Official input / output pricing Estimated per call
Claude Opus 5 claude-opus-5 $5 / $25 per MTok $0.18
Claude Sonnet 5 claude-sonnet-5 $3 / $15 per MTok standard pricing $0.09

The per-call values follow the repository’s existing approximate call-pricing convention.

Testing

  • go test ./api ./mcp/payment ./mcp/provider ./store
  • go vet ./api ./mcp/payment ./mcp/provider ./store
  • cd web && npm run test — 128 tests passed
  • cd web && npm run build

Security Impact

  • Secrets/keys handling changed? No
  • New/changed public API endpoints? No
  • User input validation affected? No

Compatibility

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • Existing Claude model selections remain valid; only the default changes to 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.

@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🟢 Small (40 lines: +36 -4)

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
api/errors.go
api/handler_wallet.go
cmd/e2e_builder_fee/main.go
market/types.go
mcp/config.go
mcp/context_guard_test.go
mcp/options.go
mcp/request.go
mcp/request_builder.go
provider/hyperliquid/kline.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🔴 Large (30120 lines: +29064 -1056)

💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review.

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
agent/brain.go
agent/execution_state.go
agent/onboard.go
agent/scheduler.go
agent/sentinel.go
agent/skill_dag.go
agent/skill_dag_runtime.go
agent/skill_dispatcher.go
agent/skill_management_handlers.go
agent/stock.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

@Hansen1018 Hansen1018 changed the title feat(ai): add Claude 5 model support feat(ai): add Claude Opus 5 and Sonnet 5 support Jul 25, 2026
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.
@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🟢 Small (40 lines: +36 -4)

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
api/errors.go
api/handler_wallet.go
cmd/e2e_builder_fee/main.go
market/types.go
mcp/config.go
mcp/context_guard_test.go
mcp/options.go
mcp/request.go
mcp/request_builder.go
provider/hyperliquid/kline.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🟢 Small (40 lines: +36 -4)

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
api/errors.go
api/handler_wallet.go
cmd/e2e_builder_fee/main.go
market/types.go
mcp/config.go
mcp/context_guard_test.go
mcp/options.go
mcp/request.go
mcp/request_builder.go
provider/hyperliquid/kline.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.
@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🔴 Large (2309 lines: +2028 -281)

💡 Suggestion: This is a large PR. Consider breaking it into smaller, focused PRs for easier review.

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
api/errors.go
api/handler_wallet.go
cmd/e2e_builder_fee/main.go
market/types.go
mcp/config.go
mcp/context_guard_test.go
mcp/options.go
mcp/request.go
mcp/request_builder.go
provider/hyperliquid/kline.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

Hansen1018 and others added 2 commits July 30, 2026 18:25
# 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
@github-actions

Copy link
Copy Markdown

🤖 Advisory Check Results

These are advisory checks to help improve code quality. They won't block your PR from being merged.

📋 PR Information

Title Format: ✅ Good - Follows Conventional Commits
PR Size: 🟢 Small (116 lines: +114 -2)

🔧 Backend Checks

Go Formatting: ⚠️ Needs formatting

Files needing formatting
api/errors.go
api/handler_wallet.go
cmd/e2e_builder_fee/main.go
market/types.go
mcp/config.go
mcp/context_guard_test.go
mcp/options.go
mcp/request.go
mcp/request_builder.go
provider/hyperliquid/kline.go

Go Vet: ✅ Good
Tests: ✅ Passed

Fix locally:

go fmt ./...      # Format code
go vet ./...      # Check for issues
go test ./...     # Run tests

⚛️ Frontend Checks

Build & Type Check: ✅ Success

Fix locally:

cd web
npm run build  # Test build (includes type checking)

📖 Resources

Questions? 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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants