Commit Graph

1135 Commits

Author SHA1 Message Date
tinkle-community
3c061aee94 fix(security): tighten strategy-market iframe permissions
Two issues in the prior commit that the embedded vergex.trade explore
iframe did not actually need:

  1. `allow=clipboard-write` granted the iframe silent write access to
     the user's clipboard via the Clipboard API. A compromised or
     compromised-by-injection vergex page could overwrite copied
     content — classic clipboard-hijack pattern (e.g. swap a copied
     wallet address right before the user pastes it into a send form).
     The explore view does not need this capability; drop it. Matches
     the existing DataPage.tsx iframe pattern.

  2. No `sandbox` attribute, so the iframe ran with full implicit
     permissions: arbitrary scripts, form submission, top-level
     navigation, modals, pointer lock, etc. Add an explicit sandbox
     whitelist that grants only what the explore view actually uses:

       allow-scripts allow-same-origin allow-forms
       allow-popups allow-popups-to-escape-sandbox

     Notably withheld:
       - allow-top-navigation: the iframe cannot redirect the NOFX
         shell to an arbitrary URL.
       - allow-modals / allow-pointer-lock / allow-orientation-lock:
         not used by the explore page.
       - allow-storage-access-by-user-activation: keeps third-party
         storage access prompts off the embedded surface.

Verified: explore page renders identically; no sandbox-related
violations in the console (residual errors are vergex's own internal
CSP rejecting analytics + asset fetches, unrelated to our embedding).
2026-06-02 01:56:32 +08:00
tinkle-community
30c6abca74 feat(web): inline-embed vergex.trade/explore in the strategy market
vergex.trade now lists the NOFX origins in the enforced CSP
`frame-ancestors` directive for the /explore path:

  frame-ancestors 'self' https://nofxos.ai https://www.nofxos.ai
                  http://127.0.0.1:3000 http://localhost:3000

so cross-origin embedding from any NOFX deployment works. The
X-Frame-Options header is still SAMEORIGIN, but modern browsers honor
the CSP `frame-ancestors` directive when both are present (per CSP
Level 2), and the embed verifies cleanly under Chromium.

Replaces the prior fallback "open in new tab" CTA card with the same
iframe pattern DataPage.tsx already uses for vergex.trade/trending —
single iframe filling the AppChrome content area, full-screen and
clipboard permissions enabled, strict-origin referrer.
2026-06-02 01:49:22 +08:00
tinkle-community
129952859e chore(gitignore): exclude local agent/skill scaffolding
.agents/ holds editor-side agent definitions and skills-lock.json is a
local skill manifest — neither belongs in the repo. Also adds a trailing
newline so the file ends cleanly.
2026-05-31 23:59:04 +08:00
tinkle-community
7f0a9f0749 fix(hyperliquid): bump go-hyperliquid v0.26 -> v0.36 to dodge spot-meta panic
go-hyperliquid v0.26.0 crashed at startup with

    panic: runtime error: index out of range [479] with length 464
    github.com/sonirico/go-hyperliquid.NewInfo (info.go:75)
    NewExchange -> NewHyperliquidTrader -> AutoTrader.NewAutoTrader
    -> TraderManager.LoadTradersFromStore -> main.main

The library's NewInfo built the spot-asset map by indexing
`spotMeta.Tokens[spotInfo.Tokens[0]]` directly, but Hyperliquid recently
added spot tokens whose Tokens[0] value (a logical token *index*, not an
array position) was larger than the Tokens slice length. With every
restart the backend panicked before the API server bound, so the
frontend's `/api/*` proxy got connection refused on every poll and the
dashboard rendered "全是 error" toasts.

v0.36 fixes the panic by building `tokensByIndex map[int]SpotTokenInfo`
and looking up by logical index instead of position. Adopting v0.36
required two small adaptations to our wrapper:

  - trader/hyperliquid/trader.go: NewExchange grew an extra `perpDexs
    *MixedArray` argument. Passing `nil` keeps the existing
    "auto-fetch on first use" behavior.
  - trader/hyperliquid/trader_sync.go: `Info.NameToAsset(coin) int` was
    renamed to `Info.CoinToAsset(coin) (int, bool)` with an `ok` flag.
    refreshMetaIfNeeded now treats `!ok || assetID == 0` as "needs
    refresh" (the same semantic as the old `assetID == 0`).

Verified: backend rebuilds cleanly, container is healthy, all
Hyperliquid traders load, AI cycles execute, and Hyperliquid order
sync receives the full historical trade window.
2026-05-30 01:48:11 +08:00
tinkle-community
b15c2da3a9 feat(strategy): English-only XYZ stock prompt + flat-account aggression + tier promote
The strategy prompt the LLM saw for a Chinese-language single-symbol US
stock trader was an incoherent zh/en patchwork — schema in Chinese,
role definition in English, hard constraints in English, custom prompt
back in Chinese — with crypto-flavored BTC/ETH vs Altcoin labelling that
made no sense for ARM-USDC. The LLM responded by being conservative and
boring. When it finally tried to open, the validator rejected the order
because the validator classified the stock as an altcoin (1x equity cap
= 112 USDT max) while the prompt said 5x cap (= 559 USDT).

- kernel/engine_prompt.go (BuildSystemPrompt): all eight prompt sections
  now respect e.GetLanguage() consistently. For single-symbol
  Hyperliquid XYZ assets (US stocks, commodities, forex) we additionally
  force the language to English regardless of the strategy's stored
  language — US-equity reasoning lands better in English and prevents
  the language-mix incoherence. The Hard Constraints section drops the
  BTC/ETH vs Altcoin two-tier split when the strategy trades a single
  instrument and shows one Position Value Limit line tagged with the
  actual symbol. The JSON example uses that symbol instead of the
  legacy BTCUSDT/ETHUSDT. The legacy stored custom_prompt (which was
  Chinese for stock quick-creates) is replaced for XYZ assets by
  buildXYZStockCustomPrompt — a built-in English long-only stock
  briefing that includes a Flat-Account Rule: when Current Positions
  is None, the agent MUST open a long this cycle (size 40-60% probing
  if technicals are mixed, 80-100% on a confirmed breakout). This is
  the "be in the market, not on the sidelines" stance the quick-trade
  flow needed; wait/hold are reserved for when a position already
  exists.

- kernel/engine_position.go + trader/auto_trader_risk.go + agent/trade.go:
  Hyperliquid XYZ assets now use the BTC/ETH higher tier rather than
  the altcoin tier in all three position-value enforcement points. A
  shared isMajorAsset / isMajorTradeSymbol helper treats BTC/ETH crypto
  perps AND any IsXyzDexAsset symbol as the higher tier. With 5x
  equity cap, the AI's confident-open decisions on US stocks now pass
  validation instead of erroring out with "altcoin single coin position
  value cannot exceed 112 USDT".

Net result: on a flat US-stock single-symbol trader, the agent opens
a sized position with stop-loss and take-profit on the very first
flat cycle, manages it (trail / partial / cut), and reports honestly
to the user. The "agent does nothing" complaint is closed.
2026-05-29 22:15:35 +08:00
tinkle-community
d008ccc6ab fix(market): route Hyperliquid USDC perps correctly + symbol fuzzy match
A single-symbol QNT-USDC trader produced 0 candidate coins, 500 errors
from Hyperliquid, and "🚫 Dropped AI decision" warnings — the agent had
no market data to reason about, so it sat in `wait` forever. Three
chained bugs:

1. provider/hyperliquid/kline.go (IsXYZAsset / FormatCoinForAPI):
   asset detection required the base symbol to appear in the hardcoded
   StockPerpsSymbols / XYZOtherSymbols / display-alias lists. QNT, ARM,
   and every other newly-listed Hyperliquid USDC perp wasn't in the
   list, so the code routed them to the crypto path (CoinAnk) which
   doesn't have them. Now the `-USDC` suffix and `xyz:` prefix are
   trusted as definitive Hyperliquid signals — these tokens are
   Hyperliquid-specific and new listings don't require a code change.
   The hardcoded lists are kept as fallbacks for bare base symbols.

2. market/data_klines.go (getKlinesFromHyperliquid): the function
   stripped the `xyz:` prefix before calling GetCandles, defeating
   GetCandles's own FormatCoinForAPI logic. With the hardcoded list
   missing the new ticker, FormatCoinForAPI couldn't re-add the prefix
   and the request hit Hyperliquid's crypto perp endpoint — which
   returns 500 for stock-only tickers. Pass the symbol through as-is.

3. trader/auto_trader_loop.go (filterDecisionsToStrategyUniverse): the
   AI sometimes echoes a candidate as "QNTUSDC" / "QNT-USDC" / "QNTUSDT"
   / bare "QNT" instead of the canonical "xyz:QNT" we supplied. Strict
   exact-match was dropping all of them. Added a base-level key
   (strips xyz:, -USDC, -USDT, USDC, USDT, USD; normalizes display
   aliases like ROBINHOOD → HOOD) and rewrites the matched decision's
   symbol to the canonical form so the order pipeline downstream sees
   the format it expects.

After this, a single-symbol stock trader fetches real K-line data from
Hyperliquid, the AI sees real candidates, and decisions get executed
on-chain instead of silently filtered.
2026-05-29 22:14:41 +08:00
tinkle-community
e4adafa364 feat(web): quick-trade button actually trades - auto-start + honest status
The lightning button on the symbol panel was the single biggest
"agent does nothing" complaint: it created a trader and a strategy via
direct REST calls, then handed the user a hardcoded reply that read
"我没有自动启动实盘交易。请到 Traders 面板确认风控后手动 Start" —
i.e. the chat bot openly admitted it bypassed the agent and refused to
do the work the user had clearly asked for.

- web/src/lib/hyperliquidQuickTrade.ts: after createStrategy +
  createTrader (or finding an existing trader), call POST
  /api/traders/:id/start immediately. Report `started`, `reusedTrader`,
  and an optional `startError` so the chat reply can be honest about
  what happened — created vs reused, running vs failed, and why.

- web/src/pages/AgentChatPage.tsx: replace the canned "please start
  manually" reply with one that reflects reality. Success path shows
  the symbol, strategy, 5-min scan interval, and how to halt it via
  chat. Failure path surfaces the actual start error and tells the
  user the trader exists but is not running.

- web/src/lib/hyperliquidQuickTrade.ts: per-symbol prompt now routes
  on category. Stocks (category="stock") get a long-only, momentum-
  seeking prompt — break of high, volume spike, support reclaim, sector
  catalyst — because shorting individual US equities through the agent
  is rarely what the user wants. Crypto stays bidirectional but
  disciplined. The trader-level custom_prompt is rewritten in the same
  style and explicitly forbids rotating to other symbols.
2026-05-29 22:13:51 +08:00
tinkle-community
1851508353 feat(agent): make the assistant agentic - visible tools, LLM voice, full toolset
The agent felt like an artificial idiot because the LLM almost never spoke
for itself: 14+ Go paths injected fmt.Sprintf canned replies, the frontend
filtered out tool-progress events so users saw three dots for 10-20s, the
main prompt told the LLM "be a trading partner" AND "answer only what's
asked", and the planner sliced the toolset by inferred domain so a "BTC
dropped, how much am I losing?" question couldn't see positions and market
at the same time.

- agent/central_brain.go: shouldTrustDeterministicSkillReply now always
  returns false. Successful mutations (trader/strategy/model/exchange
  create/update/start/stop/delete) flow through reviewTaskCompletion so the
  LLM sees the real outcome JSON and writes the user-facing prose. The
  trade-confirmation regex path (handleTradeConfirmation) was already
  outside this code path and is unaffected.

- agent/agent.go: rewrite the Behavior section of the main system prompt.
  Replace the contradictory "answer only what's asked / don't upsell" with
  "lead with the direct answer, then optionally one relevant follow-up
  only when (a) open risk, (b) missing config, or (c) the next step is
  obvious — e.g. created, want me to start it?". Explicitly authorize
  chaining ("if the user says create and start, do both this turn") and
  ban "please wait / I'll get back to you" language because there is no
  background job to come back from.

- agent/tools.go: plannerToolsForText always returns the full 22-tool set
  (new __all__ domain). The old per-domain trimming hid manage_trader from
  market questions and execute_trade from anything that didn't look like
  an explicit trade — cross-domain reasoning was structurally blocked. The
  compact-vs-full strategy schema switch is preserved so mutation intents
  still see the full config schema.

- web/src/components/agent/{AgentStepPanel,ChatMessages}.tsx: stop
  filtering tool: steps. Map raw tool names to friendly labels with emoji
  ("get_positions" → "📊 检查持仓") in zh/en/id. Users now see what the
  agent is doing in real time instead of silence. central_brain routing
  chatter still gets dropped.

- agent/planner_tools_test.go: tests updated to assert the new
  full-toolset behavior and the compact-vs-full strategy schema switch.
2026-05-29 22:13:05 +08:00
tinkle-community
fcb73cc195 fix(deps): clear all Go vulnerabilities (govulncheck 20 -> 0)
govulncheck @ vuln.go.dev 2026-05-26 db reported 20 advisories that the
code actually calls (13 stdlib, 7 third-party). After this commit:
0 vulnerabilities affecting the code.

Third-party module bumps (within existing import sites, no API changes):
- github.com/ethereum/go-ethereum v1.16.7 -> v1.17.3
  (GO-2026-4314 / -4315 / -4507 / -4508)
- github.com/quic-go/quic-go v0.54.0 -> v0.59.1
  (GO-2025-4233 HTTP/3 QPACK header expansion DoS)
- github.com/golang-jwt/jwt/v5 v5.2.0 -> v5.3.1
  (GO-2025-3553 excessive memory allocation in jwt.Parser)
- golang.org/x/net v0.43.0 -> v0.55.0 (GO-2026-4918)

go directive: 1.25.3 -> 1.25.10 to pull stdlib patches for
net/mail, net, net/http, net/url, crypto/x509, crypto/tls, html/template
(GO-2025-4155 / -4175, GO-2026-4337 / -4340 / -4341 / -4601 / -4865 /
-4870 / -4918 / -4946 / -4947 / -4971 / -4977 / -4986). Toolchain
auto-downloads via GOTOOLCHAIN=auto; docker base golang:1.25-alpine is
already 1.25.10 so production builds are unaffected.

Verified: go build ./... clean, go vet clean, go test ./auth ./mcp
./api ./store ./trader/... all green, govulncheck reports 0.
2026-05-29 16:27:19 +08:00
tinkle-community
b9ae99da7e fix(deps): bump web transitive deps via npm audit fix
Resolves 12 local advisories (3 high, 3 moderate, 6 low) with zero
direct-dep version changes — all within existing semver ranges:

- axios 1.13.6 -> 1.16.1 (SSRF via NO_PROXY bypass, prototype pollution
  via validateStatus/parseReviver, CRLF injection in multipart bodies,
  null byte injection in URLSearchParams)
- vite 6.4.1 -> 6.4.2 (high)
- lodash 4.17.23 -> 4.18.1 (high)
- postcss 8.5.6 -> 8.5.15 (moderate)
- plus the rest of the transitive graph

package.json is unchanged. tsc passes, frontend container rebuilds
cleanly, login page renders without console errors. Verified via
docker compose up -d --build nofx-frontend.
2026-05-29 16:18:16 +08:00
tinkle-community
75832f9eb2 feat(web): redesign login page and proxy strategy market to vergex.trade
- LoginPage: two-column desktop layout with brand panel (status pill,
  gradient headline, stats strip) and form panel; single-column mobile
  layout with centered brand mark. Self-contained grid centering so
  layout no longer depends on parent flex behavior. Drop the dead
  OnboardingModeSelector (it belongs to SetupPage, not login) and add
  loader spinner, animated submit arrow, and clearer error banner.
- StrategyMarketPage: replace the 560-line bespoke marketplace with a
  branded handoff to vergex.trade/explore. Direct iframe embedding is
  currently blocked by vergex's X-Frame-Options: SAMEORIGIN and
  frame-ancestors 'self', and there is no way to reliably detect the
  block from JavaScript (load event fires for the browser error page,
  contentWindow.location throws SecurityError in both success and
  failure). The component now renders a centered card with the
  POWERED BY VERGEX.TRADE pill, headline, description, gold CTA, and
  a stats row, with all three supported languages.
- .gitignore: exclude .gstack/ (local security audit reports).
2026-05-29 16:14:46 +08:00
tinkle-community
99361cb085 fix(security): harden auth flows and lock down telegram bot tool
- config: require JWT_SECRET >=32 bytes and reject the historical
  default fallback; MustInit aborts startup under an insecure config
- api: CORS now uses CORS_ALLOWED_ORIGINS allowlist with safe
  localhost defaults instead of returning Access-Control-Allow-Origin: *
- api: /api/reset-password and /api/reset-account stay public so
  recovery still works, but require an explicit confirm phrase in the
  body to block accidental and drive-by triggers
- api: drop adoptOrphanRecords so wiping the account no longer hands
  the next registrant the previous owner's wallet keys and exchange
  API credentials
- api: getTraderFromQuery now does a soft ownership check; equity-history
  is restricted to traders with show_in_competition=true and
  GetOrderFills joins on trader_id
- telegram: bot api_request tool uses a default-deny method+path
  allowlist so prompt injection cannot reach password, exchange key,
  AI provider or wallet endpoints
- ci: drop @master / @main on trivy-action and trufflehog; pin to
  released versions with a TODO to move to SHA + Dependabot
- web: reset flows send the required confirm phrase; "Forgot account"
  copy (en/zh/id) warns that wallet and exchange keys will be lost
- docker-compose: keep ./.env mount for onboarding wallet persistence
  with an inline note on the tradeoff, drop the host-exposed pprof port
2026-05-29 07:51:26 +08:00
tinkle-community
70db3f5ba3 docs(readme): add vergex.trade backing and sync localized READMEs
- Add 'Backed by vergex.trade' banner to English and all localized READMEs
- Sync 6 localized READMEs (zh-CN, ja, ko, ru, uk, vi) to match English structure
- Add missing sections: Screenshots, Deploy to server, Architecture, Sponsors
- Remove orphaned root-level README.ja.md (now lives in docs/i18n/ja/)
2026-05-25 16:05:07 +08:00
tinklefund
f2eeea9659 docs(i18n): align localized READMEs with market positioning
- Sync localized README positioning with global market terminal messaging

- Move exchange registration and fee discount links forward

- Replace legacy AI model tables with automatic Claw402 access

- Update VergeX links across translated docs
2026-05-25 02:04:03 +08:00
tinklefund
eb73c8bdfa docs(readme): refine market positioning and Claw402 access
- Lead with global market coverage and exchange registration links

- Position Claw402 as automatic pay-as-you-go model access

- Update VergeX links and remove stale API docs reference
2026-05-25 01:56:51 +08:00
tinklefund
dea00b418c docs(readme): emphasize multi-market AI trading terminal
- Position NOFX around US stocks, commodities, forex, and crypto

- Update the README hero, feature summary, markets section, and architecture label

- Keep the copy affirmative and avoid defensive crypto-only comparisons
2026-05-25 01:35:07 +08:00
tinklefund
3b2e7027db feat(web): refresh Hyperliquid-focused product UI
- Update landing, chart, settings, and data page copy for stock trading

- Adjust branding and translations around Hyperliquid positioning

- Extend frontend config types for the updated exchange settings
2026-05-25 01:25:23 +08:00
tinklefund
f4ee723aa2 feat(agent): surface Hyperliquid stock trading context
- Add stock symbol panel and agent chat page wiring

- Update onboarding and tool visibility for focused trader flows

- Tighten related tests around configuration and trader scope
2026-05-25 01:25:10 +08:00
tinklefund
5bdffee3b0 feat(strategy): support Hyperliquid stock strategy editing
- Extend strategy storage and engine analysis for Hyperliquid defaults

- Rework coin source and indicator editors for the stock strategy flow

- Update Strategy Studio translations and page wiring
2026-05-25 01:25:05 +08:00
tinklefund
c7c003cc3c feat(trader): wire Hyperliquid wallet and quick trade flow
- Add wallet API endpoints and exchange storage fields for Hyperliquid

- Normalize quick trade order paths, symbols, and builder fee coverage

- Add frontend wallet connect and quick trade helpers
2026-05-25 01:24:58 +08:00
tinklefund
f37fc9f887 feat(hyperliquid): add stock symbol market data support
- Add Hyperliquid/XYZ symbol normalization tests and backend coverage

- Extend kline and market data lookup paths for US stock symbols

- Wire frontend data API types for stock-oriented market requests
2026-05-25 01:24:49 +08:00
tinklefund
908fc09aca feat(strategy): replace default presets with Hyperliquid US stock strategies
Remove the old generic risk-profile defaults from the user strategy bootstrap path and replace them with concrete Hyperliquid USDC equity presets that can be selected directly when creating an AI trader.

Add three ready-to-run strategy presets: a volume-ranked US stock trend preset, a fixed mega-cap preset covering AAPL-USDC/MSFT-USDC/GOOGL-USDC/AMZN-USDC/META-USDC, and a gainers-ranked US stock breakout preset.

Normalize the presets to use Hyperliquid-native stock discovery instead of AI500/OI crypto-style sources, with conservative defaults for max positions, leverage, margin usage, confidence, risk-reward, and multi-timeframe indicators.

Make default strategy synchronization idempotent for existing users: remove obsolete unused legacy preset rows, backfill the new US stock presets, and avoid overriding an already active custom strategy.

Update the trader creation modal preview labels so Hyperliquid stock ranking and fixed US stock sources are described clearly when users select a strategy.

Add API tests covering the new preset set, legacy preset cleanup, idempotent sync behavior, and preservation of an existing active custom strategy.

Verified with: go test ./api ./store; npm run build; docker compose up -d --build nofx nofx-frontend; backend /api/health; frontend HTTP 200; compose health checks.
2026-05-25 01:20:05 +08:00
shinchan-zhai
ab5873e2de refactor(agent): improve legacy loop comment and extract domain variable
Clarify the rationale for not injecting conversation history in the
legacy loop comment, and extract plannerToolDomainForText result into
a named variable for readability.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-12 00:16:20 +08:00
shinchan-zhai
d80bb31c0a fix(web): fix UI bugs and unify design tokens
- Add missing .nofx-glass CSS class (used in 20+ places but undefined)
- Fix Input component referencing undefined --brand-black/--brand-light-gray
- Unify background colors to #0B0E11 (was 3 different near-blacks)
- Switch body font from IBM Plex Mono to Inter for readability
- Improve chat bubble contrast (bg 0.03→0.05, border 0.05→0.08)
- Brighten timestamp (#2c2c42→#5a5a72) and disclaimer (#1e1e32→#4a4a62)
- Unify ::selection color to gold (was orange)
- Remove global button:hover translateY that conflicted with active:scale

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 23:51:27 +08:00
shinchan-zhai
e2ccc6b911 fix(agent): eliminate cross-turn topic pollution in legacy loop
Remove conversation history injection from thinkAndActLegacyWithStore.
Previously, the legacy loop appended all prior Q&A turns, causing the
LLM to re-answer topics from earlier conversations (e.g. strategy data
leaking into a wallet balance question). Each legacy-loop call is now
treated as a standalone request with domain-filtered tools.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 23:51:18 +08:00
shinchan-zhai
bf289e8eb3 fix(agent): reduce verbose responses — focus answers on user's question only
Root cause: when planner fails (402 payment), legacy loop dumps all system
context to LLM which outputs everything. Also final response prompt was too
weak — LLM treated all observations as required output.

Changes:
- Strengthen system prompt: "answer ONLY what user asked", no tables/tutorials
  unless requested, no self-intro repeats, no "next step" suggestions
- Add compact observation summary for final response (step summaries only,
  no raw JSON blobs)
- Domain-filtered tool selection in legacy loop to prevent over-fetching
- Fix domain routing: "钱包/wallet" → account domain (not model), with
  exchange configs included for wallet context
- Widen wallet fast-path: no longer requires "claw402" keyword
- Anti-repetition instructions in planner step selector

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 21:12:48 +08:00
shinchan-zhai
9f25bf49bf fix(agent): use provider registry for claw402, echo reasoning_content for thinking models, add Beta badge
- Agent now uses mcp.NewAIClientByProvider() for claw402 provider, ensuring
  x402 payment signing works correctly instead of generic HTTP client
- Added ReasoningContent field to Message/LLMResponse structs and wired
  serialization/parsing so DeepSeek thinking models work in multi-turn
- Added Beta badge to Agent nav tab in HeaderBar

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 20:22:32 +08:00
shinchan-zhai
b8cde34e67 feat(agent): add NOFXi agent chat workflow (#1495)
- Add NOFXi agent backend: central brain, planner runtime, skill routing,
  memory/state handling, config validation, and action execution
- Add agent chat page with SSE streaming, step/status panels, and
  user preferences
- Extend trader/model/exchange/strategy APIs and store for agent-driven
  configuration
- Add stopCh guard in async maintenance goroutine to prevent leak on Stop()
- Add timeout context for trader diagnosis LLM calls
- Add TargetRef nil guards in all execute*Action handlers
- Add ensureHistory() for nil-safe history access

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:54:53 +08:00
shinchan-zhai
32e8a03a85 merge: resolve conflicts from origin/dev into PR #1495
- Use PR branch (dev-nofxi) as authority for agent/ module code
- Merge dev's newer model names (MiniMax-M2.7, deepseek-v4-flash)
  with PR's blockrun provider entries
- Fix duplicate agent init in main.go, keep defer-based Stop()
- Fix var type bug in store/ai_model.go (model → models)
- Remove dev-only test files incompatible with PR's evolved agent code
  (to be re-synced after merge)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:52:04 +08:00
shinchan-zhai
ca8bed4a58 fix(agent): add TargetRef nil guards and ensureHistory for robustness
- Add nil checks for session.TargetRef in all four execute*Action
  handlers (Trader/Exchange/Model/Strategy) to prevent panic on
  corrupted sessions; bulk-delete and query actions are excluded
- Add ensureHistory() helper and call it in runPlannedAgentWithContextMode
  to prevent nil panic when history is not initialized

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:43:36 +08:00
shinchan-zhai
94844b7139 fix(agent): guard async maintenance goroutine and add timeout to diagnosis ctx
- Add stopCh check in runPostResponseMaintenanceAsync to respect agent
  shutdown, preventing goroutine leak on Agent.Stop()
- Replace bare context.Background() in handleTraderDiagnosisSkill with
  a 30s timeout context for proper deadline propagation

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-05-11 16:37:30 +08:00
lky-spec
e67a927a4f Refine strategy creation flow and diagnostics 2026-05-09 14:48:24 +08:00
lky-spec
0f11be77f8 Improve NOFXi agent strategy creation flow 2026-05-06 17:00:05 +08:00
lky-spec
159f27dfdd Improve NOFXi agent product handling 2026-05-02 22:55:10 +08:00
lky-spec
25d0b30ea9 Split strategy config by strategy type 2026-04-28 20:19:24 +08:00
lky-spec
2d45e7ab15 Refine agent strategy routing and config handling 2026-04-28 19:37:44 +08:00
lky-spec
fc6c42ac11 Revert "Revert "Clean up reverted strategy prompt remnants""
This reverts commit 03a307939e.
2026-04-28 15:54:37 +08:00
lky-spec
5ff7212cb3 Revert "Revert "Trim agent planning tools and validate strategy patches""
This reverts commit 3619f82796.
2026-04-28 15:54:36 +08:00
lky-spec
3619f82796 Revert "Trim agent planning tools and validate strategy patches"
This reverts commit fe0dbce367.
2026-04-28 15:53:53 +08:00
lky-spec
03a307939e Revert "Clean up reverted strategy prompt remnants"
This reverts commit 8d8a0cc72b.
2026-04-28 15:53:53 +08:00
lky-spec
8d8a0cc72b Clean up reverted strategy prompt remnants 2026-04-28 15:50:45 +08:00
lky-spec
fe0dbce367 Trim agent planning tools and validate strategy patches 2026-04-28 15:45:47 +08:00
lky-spec
b536265f93 Propagate MCP request context to HTTP calls 2026-04-28 12:22:45 +08:00
lky-spec
30a703a827 Unify agent routing and tighten exchange config 2026-04-28 11:58:58 +08:00
lky-spec
d481b3d88c Remove local-only agent artifacts 2026-04-27 10:51:09 +08:00
lky-spec
e8eafce1e0 Require explicit agent mutation targets 2026-04-26 22:38:16 +08:00
lky-spec
ce3a8582af Simplify agent skill routing and config updates 2026-04-26 22:22:12 +08:00
lky-spec
cfd91069d3 Centralize active skill field extraction 2026-04-26 20:44:09 +08:00
lky-spec
903eb591eb Improve active skill schema handling 2026-04-26 11:58:29 +08:00
shinchan-zhai
0d3b9536d5 merge: resolve conflicts from origin/main into dev
All conflicts were in frontend files where main had beginner-mode features
(BeginnerGuideCards, Claw402 balance alerts, mode switcher, actionable error
helpers) that dev intentionally simplified. Kept dev's version in every case.
Removed unused navigate import in SettingsPage after conflict resolution.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-26 00:13:31 +08:00