mirror of
https://github.com/NoFxAiOS/nofx.git
synced 2026-07-07 13:00:59 +08:00
feat: wire NOFXi Agent into Telegram bot
- Add NOFXiAgent interface and SetNOFXiAgent() in telegram/bot.go - Telegram messages now route through the unified agent.Agent instead of the legacy telegram/agent package - Language hint injected from Telegram config for proper i18n - Legacy telegram/agent path preserved as fallback - Agent created before Telegram bot starts in main.go - Build verified, API tested
This commit is contained in:
12
main.go
12
main.go
@@ -142,10 +142,7 @@ func main() {
|
||||
}
|
||||
}()
|
||||
|
||||
// Start Telegram bot (if TELEGRAM_BOT_TOKEN is configured)
|
||||
go telegram.Start(cfg, st, telegramReloadCh)
|
||||
|
||||
// Start NOFXi Agent (proactive intelligence layer)
|
||||
// Start NOFXi Agent (proactive intelligence layer) — must be created BEFORE Telegram bot
|
||||
nofxiAgent := nofxiagent.New(traderManager, st, nil, slog.Default())
|
||||
|
||||
// Try to get an AI client from existing trader configs
|
||||
@@ -164,6 +161,13 @@ func main() {
|
||||
agentWeb := nofxiagent.NewWebHandler(nofxiAgent, slog.Default())
|
||||
server.RegisterAgentHandler(agentWeb)
|
||||
|
||||
// Wire NOFXi Agent into Telegram bot — messages route through the unified agent
|
||||
telegram.SetNOFXiAgent(nofxiAgent)
|
||||
logger.Info("🔗 NOFXi Agent connected to Telegram bot")
|
||||
|
||||
// Start Telegram bot (if token is configured)
|
||||
go telegram.Start(cfg, st, telegramReloadCh)
|
||||
|
||||
logger.Info("🧠 NOFXi Agent started (sentinel + brain + scheduler + web:8900)")
|
||||
|
||||
// Wait for interrupt signal
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package telegram
|
||||
|
||||
import (
|
||||
"context"
|
||||
"nofx/api"
|
||||
"nofx/config"
|
||||
"nofx/logger"
|
||||
@@ -17,6 +18,30 @@ import (
|
||||
tgbotapi "github.com/go-telegram-bot-api/telegram-bot-api/v5"
|
||||
)
|
||||
|
||||
// NOFXiAgent is the interface that the new agent.Agent satisfies.
|
||||
// When set, Telegram messages are routed through it instead of the legacy telegram/agent package.
|
||||
type NOFXiAgent interface {
|
||||
HandleMessage(ctx context.Context, userID int64, text string) (string, error)
|
||||
}
|
||||
|
||||
var (
|
||||
nofxiAgentMu sync.RWMutex
|
||||
nofxiAgent NOFXiAgent
|
||||
)
|
||||
|
||||
// SetNOFXiAgent registers the new NOFXi agent for Telegram message routing.
|
||||
func SetNOFXiAgent(a NOFXiAgent) {
|
||||
nofxiAgentMu.Lock()
|
||||
defer nofxiAgentMu.Unlock()
|
||||
nofxiAgent = a
|
||||
}
|
||||
|
||||
func getNOFXiAgent() NOFXiAgent {
|
||||
nofxiAgentMu.RLock()
|
||||
defer nofxiAgentMu.RUnlock()
|
||||
return nofxiAgent
|
||||
}
|
||||
|
||||
// Start initializes and runs the Telegram bot in a blocking supervisor loop.
|
||||
// Supports hot-reload: when a signal is sent on reloadCh, the bot restarts
|
||||
// with the latest token (re-read from DB or env). Must be called as a goroutine from main.go.
|
||||
@@ -208,25 +233,46 @@ func runBot(token string, cfg *config.Config, st *store.Store) bool {
|
||||
placeholderID = sent.MessageID
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
lastEdit time.Time
|
||||
)
|
||||
onChunk := func(accumulated string) {
|
||||
if placeholderID == 0 {
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if accumulated != "⏳" && time.Since(lastEdit) < time.Second {
|
||||
return
|
||||
}
|
||||
lastEdit = time.Now()
|
||||
edit := tgbotapi.NewEditMessageText(chatID, placeholderID, accumulated)
|
||||
bot.Send(edit) //nolint:errcheck
|
||||
}
|
||||
var reply string
|
||||
|
||||
reply := agents.Run(chatID, text, onChunk)
|
||||
// Route through NOFXi Agent if available (new unified architecture),
|
||||
// otherwise fall back to legacy telegram/agent manager.
|
||||
if na := getNOFXiAgent(); na != nil {
|
||||
lang := st.TelegramConfig().GetLanguage()
|
||||
msg := text
|
||||
if lang != "" {
|
||||
msg = "[lang:" + lang + "] " + text
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 55*time.Second)
|
||||
resp, err := na.HandleMessage(ctx, chatID, msg)
|
||||
cancel()
|
||||
if err != nil {
|
||||
logger.Errorf("NOFXi agent error: %v", err)
|
||||
reply = "AI assistant temporarily unavailable. Please try again."
|
||||
} else {
|
||||
reply = resp
|
||||
}
|
||||
} else {
|
||||
// Legacy path: stream via telegram/agent
|
||||
var (
|
||||
mu sync.Mutex
|
||||
lastEdit time.Time
|
||||
)
|
||||
onChunk := func(accumulated string) {
|
||||
if placeholderID == 0 {
|
||||
return
|
||||
}
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
if accumulated != "⏳" && time.Since(lastEdit) < time.Second {
|
||||
return
|
||||
}
|
||||
lastEdit = time.Now()
|
||||
edit := tgbotapi.NewEditMessageText(chatID, placeholderID, accumulated)
|
||||
bot.Send(edit) //nolint:errcheck
|
||||
}
|
||||
reply = agents.Run(chatID, text, onChunk)
|
||||
}
|
||||
|
||||
if placeholderID != 0 {
|
||||
edit := tgbotapi.NewEditMessageText(chatID, placeholderID, reply)
|
||||
|
||||
Reference in New Issue
Block a user