mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-19 02:14:35 +08:00
feat: add blockRun (x402 USDC) support to all AI model consumers
- telegram/bot.go: add blockrun-base, blockrun-sol, minimax to clientForProvider; fix newLLMClient to prefer TelegramConfig.ModelID over GetDefault; log USDC payment provider usage - debate/engine.go: add blockrun-base, blockrun-sol to InitializeClients - api/strategy.go: add blockrun-base, blockrun-sol to runRealAITest - backtest/ai_client.go: add blockrun-base, blockrun-sol to configureMCPClient
This commit is contained in:
@@ -668,6 +668,12 @@ func (s *Server) runRealAITest(userID, modelID, systemPrompt, userPrompt string)
|
||||
case "minimax":
|
||||
aiClient = mcp.NewMiniMaxClient()
|
||||
aiClient.SetAPIKey(apiKey, model.CustomAPIURL, model.CustomModelName)
|
||||
case "blockrun-base":
|
||||
aiClient = mcp.NewBlockRunBaseClient()
|
||||
aiClient.SetAPIKey(apiKey, "", model.CustomModelName)
|
||||
case "blockrun-sol":
|
||||
aiClient = mcp.NewBlockRunSolClient()
|
||||
aiClient.SetAPIKey(apiKey, "", model.CustomModelName)
|
||||
default:
|
||||
// Use generic client
|
||||
aiClient = mcp.NewClient()
|
||||
|
||||
@@ -78,6 +78,20 @@ func configureMCPClient(cfg BacktestConfig, base mcp.AIClient) (mcp.AIClient, er
|
||||
mmC := mcp.NewMiniMaxClientWithOptions()
|
||||
mmC.(*mcp.MiniMaxClient).SetAPIKey(cfg.AICfg.APIKey, cfg.AICfg.BaseURL, cfg.AICfg.Model)
|
||||
return mmC, nil
|
||||
case "blockrun-base":
|
||||
if cfg.AICfg.APIKey == "" {
|
||||
return nil, fmt.Errorf("blockrun-base provider requires wallet private key")
|
||||
}
|
||||
brBase := mcp.NewBlockRunBaseClient()
|
||||
brBase.SetAPIKey(cfg.AICfg.APIKey, "", cfg.AICfg.Model)
|
||||
return brBase, nil
|
||||
case "blockrun-sol":
|
||||
if cfg.AICfg.APIKey == "" {
|
||||
return nil, fmt.Errorf("blockrun-sol provider requires wallet keypair")
|
||||
}
|
||||
brSol := mcp.NewBlockRunSolClient()
|
||||
brSol.SetAPIKey(cfg.AICfg.APIKey, "", cfg.AICfg.Model)
|
||||
return brSol, nil
|
||||
case "custom":
|
||||
if cfg.AICfg.BaseURL == "" || cfg.AICfg.APIKey == "" || cfg.AICfg.Model == "" {
|
||||
return nil, fmt.Errorf("custom provider requires base_url, api key and model")
|
||||
|
||||
@@ -99,6 +99,10 @@ func (e *DebateEngine) InitializeClients(participants []*store.DebateParticipant
|
||||
client = mcp.NewKimiClient()
|
||||
case "minimax":
|
||||
client = mcp.NewMiniMaxClient()
|
||||
case "blockrun-base":
|
||||
client = mcp.NewBlockRunBaseClient()
|
||||
case "blockrun-sol":
|
||||
client = mcp.NewBlockRunSolClient()
|
||||
default:
|
||||
client = mcp.New()
|
||||
}
|
||||
|
||||
@@ -266,15 +266,39 @@ func sendMarkdownMsg(bot *tgbotapi.BotAPI, chatID int64, text string) {
|
||||
// ── LLM client ───────────────────────────────────────────────────────────────
|
||||
|
||||
func newLLMClient(st *store.Store, userID string) mcp.AIClient {
|
||||
// 1. Prefer the model explicitly configured for Telegram (Settings → Telegram → AI Model)
|
||||
if tgCfg, err := st.TelegramConfig().Get(); err == nil && tgCfg.ModelID != "" {
|
||||
if model, err := st.AIModel().Get(userID, tgCfg.ModelID); err == nil && model.Enabled {
|
||||
apiKey := string(model.APIKey)
|
||||
if apiKey != "" {
|
||||
client := clientForProvider(model.Provider)
|
||||
client.SetAPIKey(apiKey, model.CustomAPIURL, model.CustomModelName)
|
||||
if isUSDCProvider(model.Provider) {
|
||||
logger.Infof("Telegram agent: provider=%s (USDC payment) user=%s", model.Provider, userID)
|
||||
} else {
|
||||
logger.Infof("Telegram agent: provider=%s user=%s", model.Provider, userID)
|
||||
}
|
||||
return client
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 2. Fall back to first enabled model
|
||||
if model, err := st.AIModel().GetDefault(userID); err == nil {
|
||||
apiKey := string(model.APIKey)
|
||||
if apiKey != "" {
|
||||
client := clientForProvider(model.Provider)
|
||||
client.SetAPIKey(apiKey, model.CustomAPIURL, model.CustomModelName)
|
||||
logger.Infof("Telegram agent: provider=%s user=%s", model.Provider, userID)
|
||||
if isUSDCProvider(model.Provider) {
|
||||
logger.Infof("Telegram agent: provider=%s (USDC payment) user=%s", model.Provider, userID)
|
||||
} else {
|
||||
logger.Infof("Telegram agent: provider=%s user=%s", model.Provider, userID)
|
||||
}
|
||||
return client
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Environment variable fallback
|
||||
for _, pair := range []struct{ provider, key, url string }{
|
||||
{"deepseek", os.Getenv("DEEPSEEK_API_KEY"), mcp.DefaultDeepSeekBaseURL},
|
||||
{"openai", os.Getenv("OPENAI_API_KEY"), ""},
|
||||
@@ -289,6 +313,11 @@ func newLLMClient(st *store.Store, userID string) mcp.AIClient {
|
||||
return nil
|
||||
}
|
||||
|
||||
// isUSDCProvider returns true for providers that pay per call with USDC (x402 protocol).
|
||||
func isUSDCProvider(provider string) bool {
|
||||
return provider == "blockrun-base" || provider == "blockrun-sol"
|
||||
}
|
||||
|
||||
func clientForProvider(provider string) mcp.AIClient {
|
||||
switch provider {
|
||||
case "openai":
|
||||
@@ -305,6 +334,12 @@ func clientForProvider(provider string) mcp.AIClient {
|
||||
return mcp.NewGrokClient()
|
||||
case "gemini":
|
||||
return mcp.NewGeminiClient()
|
||||
case "minimax":
|
||||
return mcp.NewMiniMaxClient()
|
||||
case "blockrun-base":
|
||||
return mcp.NewBlockRunBaseClient()
|
||||
case "blockrun-sol":
|
||||
return mcp.NewBlockRunSolClient()
|
||||
default:
|
||||
return mcp.NewDeepSeekClient()
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user