diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index d5536d1b7..2c46d8582 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -113,8 +113,7 @@ func (c *TelegramChannel) Start(ctx context.Context) error { } bh.HandleMessage(func(ctx *th.Context, message telego.Message) error { - c.commands.Help(ctx, message) - return nil + return c.commands.Help(ctx, message) }, th.CommandEqual("help")) bh.HandleMessage(func(ctx *th.Context, message telego.Message) error { return c.commands.Start(ctx, message) @@ -128,6 +127,10 @@ func (c *TelegramChannel) Start(ctx context.Context) error { return c.commands.List(ctx, message) }, 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 { return c.handleMessage(ctx, &message) }, th.AnyMessage()) diff --git a/pkg/channels/telegram_commands.go b/pkg/channels/telegram_commands.go index 259ddeb6d..4c75adecb 100644 --- a/pkg/channels/telegram_commands.go +++ b/pkg/channels/telegram_commands.go @@ -15,6 +15,7 @@ type TelegramCommander interface { Start(ctx context.Context, message telego.Message) error Show(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 { @@ -38,14 +39,18 @@ func commandArgs(text string) string { } func (c *cmd) Help(ctx context.Context, message telego.Message) error { - msg := `/start - Start the bot -/help - Show this help message -/show [model|channel] - Show current configuration -/show agents - Show registered agents -/list [models|channels] - List available options -/list agents - List registered agents -/switch model to - Switch to a different model - ` + msg := `Available commands: + /help Show this help message + /new Start a new conversation + /status Show current session info + /show model Show current model + /show channel Show current channel + /show agents Show registered agents + /list models List available models + /list channels List enabled channels + /list agents List registered agents + /switch model to Switch to a different model + /switch channel to Switch target channel` _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ ChatID: telego.ChatID{ID: message.Chat.ID}, Text: msg, @@ -72,7 +77,7 @@ func (c *cmd) Show(ctx context.Context, message telego.Message) error { if args == "" { _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ ChatID: telego.ChatID{ID: message.Chat.ID}, - Text: "Usage: /show [model|channel]", + Text: "Usage: /show [model|channel|agents]", ReplyParameters: &telego.ReplyParameters{ MessageID: message.MessageID, }, @@ -83,13 +88,14 @@ func (c *cmd) Show(ctx context.Context, message telego.Message) error { var response string switch args { case "model": - response = fmt.Sprintf("Current Model: %s (Provider: %s)", - c.config.Agents.Defaults.Model, - c.config.Agents.Defaults.Provider) + response = fmt.Sprintf("Current model: %s", c.config.Agents.Defaults.Model) 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: - 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{ @@ -107,7 +113,7 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error { if args == "" { _, err := c.bot.SendMessage(ctx, &telego.SendMessageParams{ ChatID: telego.ChatID{ID: message.Chat.ID}, - Text: "Usage: /list [models|channels]", + Text: "Usage: /list [models|channels|agents]", ReplyParameters: &telego.ReplyParameters{ MessageID: message.MessageID, }, @@ -118,34 +124,40 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error { var response string switch args { case "models": - provider := c.config.Agents.Defaults.Provider - if provider == "" { - provider = "configured default" + var lines []string + // List per-agent models to match agent loop output + 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": - var enabled []string - if c.config.Channels.Telegram.Enabled { - enabled = append(enabled, "telegram") + enabled := c.listEnabledChannels() + if len(enabled) == 0 { + response = "No channels enabled" + } else { + response = fmt.Sprintf("Enabled channels: %s", strings.Join(enabled, ", ")) } - 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") - } - response = fmt.Sprintf("Enabled Channels:\n- %s", strings.Join(enabled, "\n- ")) + + case "agents": + agentIDs := c.listAgentIDs() + response = fmt.Sprintf("Registered agents: %s", strings.Join(agentIDs, ", ")) 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{ @@ -157,3 +169,98 @@ func (c *cmd) List(ctx context.Context, message telego.Message) error { }) return err } + +func (c *cmd) Switch(ctx context.Context, message telego.Message) error { + args := commandArgs(message.Text) + + // Parse: "model to " or "channel to " + 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 ", + 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 +}