From 97f309c9b5a4915b5b43b98ec7d65ce4f0e22c5a Mon Sep 17 00:00:00 2001 From: tinkle-community Date: Sun, 8 Mar 2026 18:31:05 +0800 Subject: [PATCH] fix(telegram): newLLMClient uses bound user's model, not any user's model MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit GetAnyEnabled() searched across all users in DB — if user B has an enabled model, bot could use their API key while acting as user A. Now uses GetDefault(botUserID) which only looks up the bound user's enabled model, matching the same user scope as all API calls. --- telegram/bot.go | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/telegram/bot.go b/telegram/bot.go index 5e0b1a68..c26298a7 100644 --- a/telegram/bot.go +++ b/telegram/bot.go @@ -90,7 +90,7 @@ func runBot(token string, cfg *config.Config, st *store.Store) bool { // Wire the AI agent manager. API docs are auto-generated from registered routes. agents := agent.NewManager(cfg.APIServerPort, botToken, botUserID, - func() mcp.AIClient { return newLLMClient(st) }, + func() mcp.AIClient { return newLLMClient(st, botUserID) }, api.GetAPIDocs(), ) @@ -209,12 +209,12 @@ func sendMsg(bot *tgbotapi.BotAPI, chatID int64, text string) { bot.Send(msg) //nolint:errcheck } -// newLLMClient builds an LLM client for the agent. -// Priority: DB-configured model (Web UI) > environment variables. +// newLLMClient builds an LLM client for the agent using the bound user's enabled model. +// Priority: bound user's DB model > environment variables. // Uses provider-specific constructors to ensure correct default base URLs and models. -func newLLMClient(st *store.Store) mcp.AIClient { - // 1. Try any enabled model from DB (user configured via Web UI, any user_id) - if model, err := st.AIModel().GetAnyEnabled(); err == nil { +func newLLMClient(st *store.Store, userID string) mcp.AIClient { + // 1. Try the bound user's enabled model from DB (configured via Web UI) + if model, err := st.AIModel().GetDefault(userID); err == nil { apiKey := string(model.APIKey) if apiKey != "" { client := clientForProvider(model.Provider) @@ -225,7 +225,7 @@ func newLLMClient(st *store.Store) mcp.AIClient { } logger.Warnf("Telegram: DB model found (provider=%s) but API key is empty after decryption", model.Provider) } else { - logger.Warnf("Telegram: no enabled model in DB (%v), trying env vars", err) + logger.Warnf("Telegram: no enabled model for user %s (%v), trying env vars", userID, err) } // 2. Fall back to environment variables