mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
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
This commit is contained in:
@@ -286,7 +286,7 @@ func TestLoadExchangeOptionsHidesInvisibleExchangeRows(t *testing.T) {
|
||||
}).Error; err != nil {
|
||||
t.Fatalf("seed legacy hidden exchange: %v", err)
|
||||
}
|
||||
if _, err := st.Exchange().Create("default", "okx", "我的主力OKX账户", true, "api-test", "secret-test", "pass-test", false, "", false, "", "", "", "", "", "", 0); err != nil {
|
||||
if _, err := st.Exchange().Create("default", "okx", "我的主力OKX账户", true, "api-test", "secret-test", "pass-test", false, "", false, false, "", "", "", "", "", "", 0); err != nil {
|
||||
t.Fatalf("create visible exchange: %v", err)
|
||||
}
|
||||
|
||||
@@ -307,7 +307,7 @@ func TestDescribeExchangeIncludesTypeSpecificVisibleFields(t *testing.T) {
|
||||
}
|
||||
a := New(nil, st, DefaultConfig(), slog.Default())
|
||||
|
||||
hyperID, err := st.Exchange().Create("default", "hyperliquid", "Dex Pro", true, "hyper-api-key", "", "", true, "0xabc", true, "", "", "", "", "", "", 0)
|
||||
hyperID, err := st.Exchange().Create("default", "hyperliquid", "Dex Pro", true, "hyper-api-key", "", "", true, "0xabc", true, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed hyperliquid exchange: %v", err)
|
||||
}
|
||||
@@ -321,7 +321,7 @@ func TestDescribeExchangeIncludesTypeSpecificVisibleFields(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
lighterID, err := st.Exchange().Create("default", "lighter", "Lighter Main", false, "", "", "", false, "", true, "", "", "", "wallet-1", "", "lighter-secret", 7)
|
||||
lighterID, err := st.Exchange().Create("default", "lighter", "Lighter Main", false, "", "", "", false, "", true, false, "", "", "", "wallet-1", "", "lighter-secret", 7)
|
||||
if err != nil {
|
||||
t.Fatalf("seed lighter exchange: %v", err)
|
||||
}
|
||||
@@ -463,7 +463,7 @@ func TestToolUpdateTraderRejectsRenameOutsideManualPanel(t *testing.T) {
|
||||
if err := st.AIModel().UpdateWithName("default", "default_deepseek", "DeepSeek", true, "sk-test-12345", "", "deepseek-chat"); err != nil {
|
||||
t.Fatalf("seed model: %v", err)
|
||||
}
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, "", "", "", "", "", "", 0)
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed exchange: %v", err)
|
||||
}
|
||||
@@ -515,7 +515,7 @@ func TestToolCreateTraderResponseHidesLegacyTraderTuningFields(t *testing.T) {
|
||||
if err := st.AIModel().UpdateWithName("default", "default_deepseek", "DeepSeek", true, "sk-test-12345", "", "deepseek-chat"); err != nil {
|
||||
t.Fatalf("seed model: %v", err)
|
||||
}
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, "", "", "", "", "", "", 0)
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed exchange: %v", err)
|
||||
}
|
||||
@@ -566,7 +566,7 @@ func TestToolCreateTraderAutoReadsInitialBalanceFromExchange(t *testing.T) {
|
||||
if err := st.AIModel().UpdateWithName("default", "default_deepseek", "DeepSeek", true, "sk-test-12345", "", "deepseek-chat"); err != nil {
|
||||
t.Fatalf("seed model: %v", err)
|
||||
}
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, "", "", "", "", "", "", 0)
|
||||
exchangeID, err := st.Exchange().Create("default", "binance", "Main", true, "api-test", "secret-test", "", false, "", false, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed exchange: %v", err)
|
||||
}
|
||||
|
||||
@@ -455,7 +455,7 @@ func (a *Agent) saveSetupExchange(storeUserID string, state *SetupState) (string
|
||||
storeUserID, ex.ID, true,
|
||||
apiKey, apiSecret, passphrase,
|
||||
false,
|
||||
hlWallet, hlUnified,
|
||||
hlWallet, hlUnified, false,
|
||||
"", "", "",
|
||||
"", "", "", 0,
|
||||
); err != nil {
|
||||
@@ -472,7 +472,7 @@ func (a *Agent) saveSetupExchange(storeUserID string, state *SetupState) (string
|
||||
true,
|
||||
apiKey, apiSecret, passphrase,
|
||||
false,
|
||||
hlWallet, hlUnified,
|
||||
hlWallet, hlUnified, false,
|
||||
"", "", "",
|
||||
"", "", "", 0,
|
||||
)
|
||||
|
||||
@@ -1516,6 +1516,7 @@ func (a *Agent) toolManageExchangeConfig(storeUserID, argsJSON string) string {
|
||||
testnet,
|
||||
strings.TrimSpace(args.HyperliquidWalletAddr),
|
||||
unified,
|
||||
false,
|
||||
strings.TrimSpace(args.AsterUser),
|
||||
strings.TrimSpace(args.AsterSigner),
|
||||
strings.TrimSpace(args.AsterPrivateKey),
|
||||
@@ -1647,6 +1648,7 @@ func (a *Agent) toolManageExchangeConfig(storeUserID, argsJSON string) string {
|
||||
testnet,
|
||||
hyperWallet,
|
||||
unified,
|
||||
existing.HyperliquidBuilderApproved,
|
||||
asterUser,
|
||||
asterSigner,
|
||||
strings.TrimSpace(args.AsterPrivateKey),
|
||||
@@ -2518,9 +2520,13 @@ func (a *Agent) toolStartTrader(storeUserID, traderID string) string {
|
||||
if a.traderManager == nil {
|
||||
return `{"error":"trader manager unavailable"}`
|
||||
}
|
||||
if _, err := a.store.Trader().GetFullConfig(storeUserID, traderID); err != nil {
|
||||
fullCfg, err := a.store.Trader().GetFullConfig(storeUserID, traderID)
|
||||
if err != nil {
|
||||
return fmt.Sprintf(`{"error":"trader not found or inaccessible: %s"}`, err)
|
||||
}
|
||||
if fullCfg != nil && fullCfg.Exchange != nil && fullCfg.Exchange.ExchangeType == "hyperliquid" && !fullCfg.Exchange.HyperliquidBuilderApproved {
|
||||
return `{"error":"Hyperliquid trading authorization is incomplete; reconnect Hyperliquid wallet and complete trading authorization before starting this trader"}`
|
||||
}
|
||||
if existing, err := a.traderManager.GetTrader(traderID); err == nil {
|
||||
if running, ok := existing.GetStatus()["is_running"].(bool); ok && running {
|
||||
return `{"error":"trader is already running"}`
|
||||
|
||||
@@ -372,7 +372,7 @@ func TestHydrateCreateTraderSlotReferencesNormalizesExchangeIDFromVisibleName(t
|
||||
}
|
||||
a := New(nil, st, DefaultConfig(), slog.Default())
|
||||
|
||||
exchangeID, err := st.Exchange().Create("default", "okx", "小偶", true, "api-test", "secret-test", "pass", false, "", false, "", "", "", "", "", "", 0)
|
||||
exchangeID, err := st.Exchange().Create("default", "okx", "小偶", true, "api-test", "secret-test", "pass", false, "", false, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed exchange: %v", err)
|
||||
}
|
||||
@@ -737,7 +737,7 @@ func TestBuildTraderCreateMissingPromptListsAllMissingSlots(t *testing.T) {
|
||||
if err := st.AIModel().UpdateWithName("default", "default_deepseek", "DeepSeek AI", true, "sk-test-12345", "", "deepseek-chat"); err != nil {
|
||||
t.Fatalf("seed model: %v", err)
|
||||
}
|
||||
exchangeID, err := st.Exchange().Create("default", "okx", "OKX 主账户", true, "api-test", "secret-test", "pass", false, "", false, "", "", "", "", "", "", 0)
|
||||
exchangeID, err := st.Exchange().Create("default", "okx", "OKX 主账户", true, "api-test", "secret-test", "pass", false, "", false, false, "", "", "", "", "", "", 0)
|
||||
if err != nil {
|
||||
t.Fatalf("seed exchange: %v", err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user