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:
tinkle-community
2026-03-10 17:47:19 +08:00
parent c5c5ed2a4d
commit af250825e7
4 changed files with 60 additions and 1 deletions

View File

@@ -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()
}