From 14333272d4a81aacbccbe45a68493897fd36a47d Mon Sep 17 00:00:00 2001 From: dj-oyu <68707227+dj-oyu@users.noreply.github.com> Date: Sun, 22 Feb 2026 16:48:41 +0900 Subject: [PATCH] fix: show status chat bubbles for miniapp-initiated prompts Create a Telegram placeholder before publishing to the bus so that streaming preview and tool-progress status messages are not silently discarded by EditStatus. Co-Authored-By: Claude Opus 4.6 --- cmd/picoclaw/cmd_gateway.go | 15 +++++++++++++-- pkg/channels/telegram.go | 29 +++++++++++++++++++++++++++++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/cmd/picoclaw/cmd_gateway.go b/cmd/picoclaw/cmd_gateway.go index 188aac507..f8b7a9432 100644 --- a/cmd/picoclaw/cmd_gateway.go +++ b/cmd/picoclaw/cmd_gateway.go @@ -233,7 +233,7 @@ func gatewayCmd() { if webAppURL != "" { provider := &agentLoopDataProvider{loop: agentLoop, workspace: cfg.WorkspacePath()} - sender := &telegramCommandSender{bus: msgBus} + sender := &telegramCommandSender{bus: msgBus, channelManager: channelManager} miniappNotifier = miniapp.NewStateNotifier() handler := miniapp.NewHandler(provider, sender, cfg.Channels.Telegram.Token, miniappNotifier) agentLoop.OnStateChange = miniappNotifier.Notify @@ -507,10 +507,21 @@ func collectGitRepoInfo(gitRoot string) miniapp.GitInfo { // telegramCommandSender injects Mini App commands into the message bus. type telegramCommandSender struct { - bus *bus.MessageBus + bus *bus.MessageBus + channelManager *channels.Manager } func (s *telegramCommandSender) SendCommand(senderID, chatID, command string) { + // Create a placeholder so status messages (streaming preview, tool progress) + // are visible to the user while the LLM processes the request. + if s.channelManager != nil { + if ch, ok := s.channelManager.GetChannel("telegram"); ok { + if tc, ok := ch.(*channels.TelegramChannel); ok { + tc.CreatePlaceholder(context.Background(), chatID) + } + } + } + s.bus.PublishInbound(bus.InboundMessage{ Channel: "telegram", SenderID: senderID, diff --git a/pkg/channels/telegram.go b/pkg/channels/telegram.go index 80d09b82b..f1a0f5266 100644 --- a/pkg/channels/telegram.go +++ b/pkg/channels/telegram.go @@ -194,6 +194,35 @@ func (c *TelegramChannel) Stop(ctx context.Context) error { return nil } +// CreatePlaceholder sends a "Thinking..." placeholder for the given chatID +// so that subsequent IsStatus messages can update it via EditStatus. +func (c *TelegramChannel) CreatePlaceholder(ctx context.Context, chatID string) error { + if !c.IsRunning() { + return nil + } + cid, err := parseChatID(chatID) + if err != nil { + return err + } + + // Stop any previous thinking animation + if prevStop, ok := c.stopThinking.Load(chatID); ok { + if cf, ok := prevStop.(*thinkingCancel); ok && cf != nil { + cf.Cancel() + } + } + + _, thinkCancel := context.WithTimeout(ctx, 5*time.Minute) + c.stopThinking.Store(chatID, &thinkingCancel{fn: thinkCancel}) + + pMsg, err := c.bot.SendMessage(ctx, tu.Message(tu.ID(cid), "Thinking... 💭")) + if err != nil { + return err + } + c.placeholders.Store(chatID, pMsg.MessageID) + return nil +} + func (c *TelegramChannel) EditStatus(ctx context.Context, msg bus.OutboundMessage) error { if !c.IsRunning() { return nil