From 132fd93072e128222b7d54c3654c6526d7141360 Mon Sep 17 00:00:00 2001 From: shinchan-zhai Date: Sun, 26 Apr 2026 00:00:26 +0800 Subject: [PATCH] fix(agent,trader): guard nil TargetRef in skill handlers and fix toast indentation - Add nil checks for session.TargetRef in all four execute*Action handlers (Trader/Exchange/Model/Strategy) to prevent panic on corrupted sessions; actions that don't need a target (query/query_list/create) are excluded. - Fix toast.success indentation in handleToggleTrader so success messages only fire when the API call actually succeeds. Co-Authored-By: Claude Opus 4.6 --- agent/skill_execution_handlers.go | 24 +++++++++++++++++++++ web/src/components/trader/AITradersPage.tsx | 4 ++-- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/agent/skill_execution_handlers.go b/agent/skill_execution_handlers.go index 6b6930fa..791e69fa 100644 --- a/agent/skill_execution_handlers.go +++ b/agent/skill_execution_handlers.go @@ -331,6 +331,12 @@ func applyStrategyConfigPatch(cfg *store.StrategyConfig, field, value string) er } func (a *Agent) executeTraderManagementAction(storeUserID string, userID int64, lang, text string, session skillSession) string { + if session.TargetRef == nil && session.Action != "query" && session.Action != "query_list" && session.Action != "create" { + if lang == "zh" { + return "请先告诉我你要操作哪个交易员。" + } + return "Please specify which trader you want to manage." + } switch session.Action { case "query", "query_list": return formatReadFastPathResponse(lang, "list_traders", a.toolListTraders(storeUserID)) @@ -507,6 +513,12 @@ func (a *Agent) executeTraderManagementAction(storeUserID string, userID int64, } func (a *Agent) executeExchangeManagementAction(storeUserID string, userID int64, lang, text string, session skillSession) string { + if session.TargetRef == nil && session.Action != "query" && session.Action != "query_list" && session.Action != "create" { + if lang == "zh" { + return "请先告诉我你要操作哪个交易所配置。" + } + return "Please specify which exchange config you want to manage." + } switch session.Action { case "query_detail": if detail, ok := a.describeExchange(storeUserID, lang, session.TargetRef); ok { @@ -624,6 +636,12 @@ func (a *Agent) executeExchangeManagementAction(storeUserID string, userID int64 } func (a *Agent) executeModelManagementAction(storeUserID string, userID int64, lang, text string, session skillSession) string { + if session.TargetRef == nil && session.Action != "query" && session.Action != "query_list" && session.Action != "create" { + if lang == "zh" { + return "请先告诉我你要操作哪个模型配置。" + } + return "Please specify which model config you want to manage." + } switch session.Action { case "query_detail": if detail, ok := a.describeModel(storeUserID, lang, session.TargetRef); ok { @@ -803,6 +821,12 @@ func normalizeModelName(name string) string { } func (a *Agent) executeStrategyManagementAction(storeUserID string, userID int64, lang, text string, session skillSession) string { + if session.TargetRef == nil && session.Action != "query" && session.Action != "query_list" && session.Action != "create" { + if lang == "zh" { + return "请先告诉我你要操作哪个策略。" + } + return "Please specify which strategy you want to manage." + } switch session.Action { case "query", "query_list": return formatReadFastPathResponse(lang, "get_strategies", a.toolGetStrategies(storeUserID)) diff --git a/web/src/components/trader/AITradersPage.tsx b/web/src/components/trader/AITradersPage.tsx index 9fd1678f..a1d94a1a 100644 --- a/web/src/components/trader/AITradersPage.tsx +++ b/web/src/components/trader/AITradersPage.tsx @@ -298,10 +298,10 @@ export function AITradersPage({ onTraderSelect }: AITradersPageProps) { try { if (running) { await api.stopTrader(traderId) - toast.success(t('aiTradersToast.stopped', language)) + toast.success(t('aiTradersToast.stopped', language)) } else { await api.startTrader(traderId) - toast.success(t('aiTradersToast.started', language)) + toast.success(t('aiTradersToast.started', language)) } await mutateTraders()