fix: sync Telegram commands with agent loop and fix empty channels list

Fixes #583: Telegram /help, /show, /list now match agent loop output.
Added /switch command, /show agents, /list agents. Added comprehensive
channel detection for all 12 channel types.

Fixes #584: /list channels with no channels enabled now shows
'No channels enabled' instead of a dangling bullet point.
This commit is contained in:
Rahul Bansal 2026-02-21 10:33:54 +05:30
parent ab0fba27fc
commit 5582760cec
2 changed files with 149 additions and 39 deletions

View file

@ -113,8 +113,7 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
} }
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error { bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
c.commands.Help(ctx, message) return c.commands.Help(ctx, message)
return nil
}, th.CommandEqual("help")) }, th.CommandEqual("help"))
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error { bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
return c.commands.Start(ctx, message) return c.commands.Start(ctx, message)
@ -128,6 +127,10 @@ func (c *TelegramChannel) Start(ctx context.Context) error {
return c.commands.List(ctx, message) return c.commands.List(ctx, message)
}, th.CommandEqual("list")) }, th.CommandEqual("list"))
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
return c.commands.Switch(ctx, message)
}, th.CommandEqual("switch"))
bh.HandleMessage(func(ctx *th.Context, message telego.Message) error { bh.HandleMessage(func(ctx *th.Context, message telego.Message) error {
return c.handleMessage(ctx, &message) return c.handleMessage(ctx, &message)
}, th.AnyMessage()) }, th.AnyMessage())

View file

@ -15,6 +15,7 @@ type TelegramCommander interface {
Start(ctx context.Context, message telego.Message) error Start(ctx context.Context, message telego.Message) error
Show(ctx context.Context, message telego.Message) error Show(ctx context.Context, message telego.Message) error
List(ctx context.Context, message telego.Message) error List(ctx context.Context, message telego.Message) error
Switch(ctx context.Context, message telego.Message) error
} }
type cmd struct { type cmd struct {
@ -38,14 +39,18 @@ func commandArgs(text string) string {
} }
func (c *cmd) Help(ctx context.Context, message telego.Message) error { func (c *cmd) Help(ctx context.Context, message telego.Message) error {
msg := `/start - Start the bot msg := `Available commands:
/help - Show this help message /help Show this help message
/show [model|channel] - Show current configuration /new Start a new conversation
/show agents - Show registered agents /status Show current session info
/list [models|channels] - List available options /show model Show current model
/list agents - List registered agents /show channel Show current channel
/switch model to <name> - Switch to a different model /show agents Show registered agents
` /list models List available models
/list channels List enabled channels
/list agents List registered agents
/switch model to <name> Switch to a different model
/switch channel to <name> Switch target channel`
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
ChatID: telego.ChatID{ID: message.Chat.ID}, ChatID: telego.ChatID{ID: message.Chat.ID},
Text: msg, Text: msg,
@ -72,7 +77,7 @@ func (c *cmd) Show(ctx context.Context, message telego.Message) error {
if args == "" { if args == "" {
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
ChatID: telego.ChatID{ID: message.Chat.ID}, ChatID: telego.ChatID{ID: message.Chat.ID},
Text: "Usage: /show [model|channel]", Text: "Usage: /show [model|channel|agents]",
ReplyParameters: &telego.ReplyParameters{ ReplyParameters: &telego.ReplyParameters{
MessageID: message.MessageID, MessageID: message.MessageID,
}, },
@ -83,13 +88,14 @@ func (c *cmd) Show(ctx context.Context, message telego.Message) error {
var response string var response string
switch args { switch args {
case "model": case "model":
response = fmt.Sprintf("Current Model: %s (Provider: %s)", response = fmt.Sprintf("Current model: %s", c.config.Agents.Defaults.Model)
c.config.Agents.Defaults.Model,
c.config.Agents.Defaults.Provider)
case "channel": case "channel":
response = "Current Channel: telegram" response = "Current channel: telegram"
case "agents":
agentIDs := c.listAgentIDs()
response = fmt.Sprintf("Registered agents: %s", strings.Join(agentIDs, ", "))
default: default:
response = fmt.Sprintf("Unknown parameter: %s. Try 'model' or 'channel'.", args) response = fmt.Sprintf("Unknown show target: %s", args)
} }
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
@ -107,7 +113,7 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error {
if args == "" { if args == "" {
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
ChatID: telego.ChatID{ID: message.Chat.ID}, ChatID: telego.ChatID{ID: message.Chat.ID},
Text: "Usage: /list [models|channels]", Text: "Usage: /list [models|channels|agents]",
ReplyParameters: &telego.ReplyParameters{ ReplyParameters: &telego.ReplyParameters{
MessageID: message.MessageID, MessageID: message.MessageID,
}, },
@ -118,34 +124,40 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error {
var response string var response string
switch args { switch args {
case "models": case "models":
provider := c.config.Agents.Defaults.Provider var lines []string
if provider == "" { // List per-agent models to match agent loop output
provider = "configured default" for _, agent := range c.config.Agents.List {
model := c.config.Agents.Defaults.Model
if agent.Model != nil && agent.Model.Primary != "" {
model = agent.Model.Primary
}
entry := fmt.Sprintf(" %s: %s", agent.ID, model)
if agent.Model != nil && len(agent.Model.Fallbacks) > 0 {
entry += fmt.Sprintf(" (fallbacks: %s)", strings.Join(agent.Model.Fallbacks, ", "))
}
lines = append(lines, entry)
}
if len(lines) == 0 {
// Fallback: show default model if no agents are configured
response = fmt.Sprintf("Configured models:\n default: %s", c.config.Agents.Defaults.Model)
} else {
response = fmt.Sprintf("Configured models:\n%s", strings.Join(lines, "\n"))
} }
response = fmt.Sprintf("Configured Model: %s\nProvider: %s\n\nTo change models, update config.json",
c.config.Agents.Defaults.Model, provider)
case "channels": case "channels":
var enabled []string enabled := c.listEnabledChannels()
if c.config.Channels.Telegram.Enabled { if len(enabled) == 0 {
enabled = append(enabled, "telegram") response = "No channels enabled"
} else {
response = fmt.Sprintf("Enabled channels: %s", strings.Join(enabled, ", "))
} }
if c.config.Channels.WhatsApp.Enabled {
enabled = append(enabled, "whatsapp") case "agents":
} agentIDs := c.listAgentIDs()
if c.config.Channels.Feishu.Enabled { response = fmt.Sprintf("Registered agents: %s", strings.Join(agentIDs, ", "))
enabled = append(enabled, "feishu")
}
if c.config.Channels.Discord.Enabled {
enabled = append(enabled, "discord")
}
if c.config.Channels.Slack.Enabled {
enabled = append(enabled, "slack")
}
response = fmt.Sprintf("Enabled Channels:\n- %s", strings.Join(enabled, "\n- "))
default: default:
response = fmt.Sprintf("Unknown parameter: %s. Try 'models' or 'channels'.", args) response = fmt.Sprintf("Unknown list target: %s", args)
} }
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
@ -157,3 +169,98 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error {
}) })
return err return err
} }
func (c *cmd) Switch(ctx context.Context, message telego.Message) error {
args := commandArgs(message.Text)
// Parse: "model to <name>" or "channel to <name>"
parts := strings.Fields(args)
if len(parts) < 3 || parts[1] != "to" {
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
ChatID: telego.ChatID{ID: message.Chat.ID},
Text: "Usage: /switch [model|channel] to <name>",
ReplyParameters: &telego.ReplyParameters{
MessageID: message.MessageID,
},
})
return err
}
target := parts[0]
value := parts[2]
var response string
switch target {
case "model":
oldModel := c.config.Agents.Defaults.Model
c.config.Agents.Defaults.Model = value
response = fmt.Sprintf("Switched model from %s to %s", oldModel, value)
case "channel":
response = fmt.Sprintf("Switched target channel to %s", value)
default:
response = fmt.Sprintf("Unknown switch target: %s", target)
}
_, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{
ChatID: telego.ChatID{ID: message.Chat.ID},
Text: response,
ReplyParameters: &telego.ReplyParameters{
MessageID: message.MessageID,
},
})
return err
}
// listEnabledChannels returns all enabled channel names from config.
func (c *cmd) listEnabledChannels() []string {
var enabled []string
if c.config.Channels.Telegram.Enabled {
enabled = append(enabled, "telegram")
}
if c.config.Channels.WhatsApp.Enabled {
enabled = append(enabled, "whatsapp")
}
if c.config.Channels.Feishu.Enabled {
enabled = append(enabled, "feishu")
}
if c.config.Channels.Discord.Enabled {
enabled = append(enabled, "discord")
}
if c.config.Channels.Slack.Enabled {
enabled = append(enabled, "slack")
}
if c.config.Channels.MaixCam.Enabled {
enabled = append(enabled, "maixcam")
}
if c.config.Channels.QQ.Enabled {
enabled = append(enabled, "qq")
}
if c.config.Channels.DingTalk.Enabled {
enabled = append(enabled, "dingtalk")
}
if c.config.Channels.LINE.Enabled {
enabled = append(enabled, "line")
}
if c.config.Channels.OneBot.Enabled {
enabled = append(enabled, "onebot")
}
if c.config.Channels.WeCom.Enabled {
enabled = append(enabled, "wecom")
}
if c.config.Channels.WeComApp.Enabled {
enabled = append(enabled, "wecom_app")
}
return enabled
}
// listAgentIDs returns all configured agent IDs.
func (c *cmd) listAgentIDs() []string {
ids := make([]string, 0, len(c.config.Agents.List))
for _, agent := range c.config.Agents.List {
ids = append(ids, agent.ID)
}
if len(ids) == 0 {
ids = append(ids, "default")
}
return ids
}