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 <noreply@anthropic.com>
This commit is contained in:
dj-oyu 2026-02-22 16:48:41 +09:00
parent 525f203699
commit 14333272d4
2 changed files with 42 additions and 2 deletions

View file

@ -233,7 +233,7 @@ func gatewayCmd() {
if webAppURL != "" { if webAppURL != "" {
provider := &agentLoopDataProvider{loop: agentLoop, workspace: cfg.WorkspacePath()} provider := &agentLoopDataProvider{loop: agentLoop, workspace: cfg.WorkspacePath()}
sender := &telegramCommandSender{bus: msgBus} sender := &telegramCommandSender{bus: msgBus, channelManager: channelManager}
miniappNotifier = miniapp.NewStateNotifier() miniappNotifier = miniapp.NewStateNotifier()
handler := miniapp.NewHandler(provider, sender, cfg.Channels.Telegram.Token, miniappNotifier) handler := miniapp.NewHandler(provider, sender, cfg.Channels.Telegram.Token, miniappNotifier)
agentLoop.OnStateChange = miniappNotifier.Notify agentLoop.OnStateChange = miniappNotifier.Notify
@ -507,10 +507,21 @@ func collectGitRepoInfo(gitRoot string) miniapp.GitInfo {
// telegramCommandSender injects Mini App commands into the message bus. // telegramCommandSender injects Mini App commands into the message bus.
type telegramCommandSender struct { type telegramCommandSender struct {
bus *bus.MessageBus bus *bus.MessageBus
channelManager *channels.Manager
} }
func (s *telegramCommandSender) SendCommand(senderID, chatID, command string) { 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{ s.bus.PublishInbound(bus.InboundMessage{
Channel: "telegram", Channel: "telegram",
SenderID: senderID, SenderID: senderID,

View file

@ -194,6 +194,35 @@ func (c *TelegramChannel) Stop(ctx context.Context) error {
return nil 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 { func (c *TelegramChannel) EditStatus(ctx context.Context, msg bus.OutboundMessage) error {
if !c.IsRunning() { if !c.IsRunning() {
return nil return nil