mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-06-06 05:51:19 +08:00
237 lines
7.3 KiB
Go
237 lines
7.3 KiB
Go
package agent
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestCreateTraderSkillCollectsMissingFieldsAndCreatesTrader(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
modelResp := a.toolManageModelConfig("user-1", `{
|
|
"action":"create",
|
|
"provider":"deepseek",
|
|
"enabled":true,
|
|
"api_key":"sk-test",
|
|
"custom_api_url":"https://api.deepseek.com/v1",
|
|
"custom_model_name":"deepseek-chat"
|
|
}`)
|
|
if strings.Contains(modelResp, `"error"`) {
|
|
t.Fatalf("failed to create model: %s", modelResp)
|
|
}
|
|
exchangeResp := a.toolManageExchangeConfig("user-1", `{
|
|
"action":"create",
|
|
"exchange_type":"okx",
|
|
"account_name":"主账户",
|
|
"enabled":true
|
|
}`)
|
|
if strings.Contains(exchangeResp, `"error"`) {
|
|
t.Fatalf("failed to create exchange: %s", exchangeResp)
|
|
}
|
|
strategyResp := a.toolManageStrategy("user-1", `{
|
|
"action":"create",
|
|
"name":"趋势策略",
|
|
"lang":"zh"
|
|
}`)
|
|
if strings.Contains(strategyResp, `"error"`) {
|
|
t.Fatalf("failed to create strategy: %s", strategyResp)
|
|
}
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 1, "zh", "帮我创建一个交易员")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "还缺这些信息") || !strings.Contains(resp, "名称") {
|
|
t.Fatalf("expected missing-field prompt, got %q", resp)
|
|
}
|
|
|
|
resp, err = a.thinkAndAct(context.Background(), "user-1", 1, "zh", "叫 波段一号")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() second turn error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已创建交易员") || !strings.Contains(resp, "波段一号") {
|
|
t.Fatalf("expected trader creation confirmation, got %q", resp)
|
|
}
|
|
|
|
listResp := a.toolListTraders("user-1")
|
|
if !strings.Contains(listResp, "波段一号") {
|
|
t.Fatalf("expected created trader in list, got %s", listResp)
|
|
}
|
|
}
|
|
|
|
func TestCreateTraderSkillRequestsStartConfirmation(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
_ = a.toolManageModelConfig("user-1", `{
|
|
"action":"create",
|
|
"provider":"openai",
|
|
"enabled":true,
|
|
"api_key":"sk-test",
|
|
"custom_api_url":"https://api.openai.com/v1",
|
|
"custom_model_name":"gpt-5"
|
|
}`)
|
|
_ = a.toolManageExchangeConfig("user-1", `{
|
|
"action":"create",
|
|
"exchange_type":"binance",
|
|
"account_name":"Main",
|
|
"enabled":true
|
|
}`)
|
|
_ = a.toolManageStrategy("user-1", `{
|
|
"action":"create",
|
|
"name":"保守策略",
|
|
"lang":"zh"
|
|
}`)
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 2, "zh", "创建一个叫“实盘一号”的交易员并启动")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "高风险动作") || !strings.Contains(resp, "确认") {
|
|
t.Fatalf("expected start confirmation prompt, got %q", resp)
|
|
}
|
|
|
|
resp, err = a.thinkAndAct(context.Background(), "user-1", 2, "zh", "先不用")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() confirmation error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已创建交易员") || strings.Contains(resp, "已创建并启动") {
|
|
t.Fatalf("expected create-without-start response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestModelDiagnosisSkillHandledWithoutAIClient(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 3, "zh", "为什么我的模型配置失败了")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "模型配置") {
|
|
t.Fatalf("expected model diagnosis response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestExchangeDiagnosisSkillHandledWithoutAIClient(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 4, "zh", "交易所 API 报 invalid signature 怎么办")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "invalid signature") && !strings.Contains(resp, "签名") {
|
|
t.Fatalf("expected exchange diagnosis response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestExchangeManagementCreateAndQuerySkill(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 5, "zh", "帮我创建一个 OKX 交易所配置")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已创建交易所配置") {
|
|
t.Fatalf("expected exchange create response, got %q", resp)
|
|
}
|
|
|
|
resp, err = a.thinkAndAct(context.Background(), "user-1", 5, "zh", "列出我的交易所配置")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() query error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "当前交易所配置") && !strings.Contains(resp, "Default") {
|
|
t.Fatalf("expected exchange query response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestModelManagementCreateSkill(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 6, "zh", "帮我创建一个 DeepSeek 模型配置")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已创建模型配置") {
|
|
t.Fatalf("expected model create response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestStrategyManagementCreateAndActivateSkill(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 7, "zh", "创建一个叫“趋势策略B”的策略")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() create error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已创建策略") {
|
|
t.Fatalf("expected strategy create response, got %q", resp)
|
|
}
|
|
|
|
resp, err = a.thinkAndAct(context.Background(), "user-1", 7, "zh", "激活趋势策略B")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() activate error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "已激活策略") {
|
|
t.Fatalf("expected strategy activate response, got %q", resp)
|
|
}
|
|
}
|
|
|
|
func TestTraderManagementQueryAndDiagnosisSkill(t *testing.T) {
|
|
a := newTestAgentWithStore(t)
|
|
|
|
modelResp := a.toolManageModelConfig("user-1", `{
|
|
"action":"create",
|
|
"provider":"openai",
|
|
"enabled":true,
|
|
"api_key":"sk-test",
|
|
"custom_api_url":"https://api.openai.com/v1",
|
|
"custom_model_name":"gpt-5"
|
|
}`)
|
|
var modelCreated struct {
|
|
Model safeModelToolConfig `json:"model"`
|
|
}
|
|
if err := json.Unmarshal([]byte(modelResp), &modelCreated); err != nil {
|
|
t.Fatalf("unmarshal model response: %v", err)
|
|
}
|
|
|
|
exchangeResp := a.toolManageExchangeConfig("user-1", `{
|
|
"action":"create",
|
|
"exchange_type":"binance",
|
|
"account_name":"Main",
|
|
"enabled":true
|
|
}`)
|
|
var exchangeCreated struct {
|
|
Exchange safeExchangeToolConfig `json:"exchange"`
|
|
}
|
|
if err := json.Unmarshal([]byte(exchangeResp), &exchangeCreated); err != nil {
|
|
t.Fatalf("unmarshal exchange response: %v", err)
|
|
}
|
|
_ = a.toolManageStrategy("user-1", `{
|
|
"action":"create",
|
|
"name":"测试策略",
|
|
"lang":"zh"
|
|
}`)
|
|
_ = a.toolManageTrader("user-1", `{
|
|
"action":"create",
|
|
"name":"测试交易员",
|
|
"ai_model_id":"`+modelCreated.Model.ID+`",
|
|
"exchange_id":"`+exchangeCreated.Exchange.ID+`",
|
|
"strategy_id":""
|
|
}`)
|
|
|
|
resp, err := a.thinkAndAct(context.Background(), "user-1", 8, "zh", "查看我的交易员")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() query error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "当前交易员") && !strings.Contains(resp, "测试交易员") {
|
|
t.Fatalf("expected trader query response, got %q", resp)
|
|
}
|
|
|
|
resp, err = a.thinkAndAct(context.Background(), "user-1", 8, "zh", "为什么我的交易员不交易")
|
|
if err != nil {
|
|
t.Fatalf("thinkAndAct() diagnosis error = %v", err)
|
|
}
|
|
if !strings.Contains(resp, "交易员运行诊断") {
|
|
t.Fatalf("expected trader diagnosis response, got %q", resp)
|
|
}
|
|
}
|