The /status command was showing 'anthropic/claude-sonnet-4-5' even when
using 'google-antigravity/claude-sonnet-4-5' because buildStatusMessage
received only the model name without the provider prefix.
When resolveConfiguredModelRef parsed a model string without a slash,
it fell back to DEFAULT_PROVIDER ('anthropic'), causing the misleading
display.
Fix: Pass the full 'provider/model' string to buildStatusMessage so
the provider is correctly extracted and displayed.
🪿 Investigated and submitted by Keith the Silly Goose
Add signalToolStart to TypingSignaler and call it from onAgentEvent
when tools begin executing. This keeps the typing indicator visible
during long-running tool operations.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Previously, startTypingLoop would return early if the typing timer was
already running, which meant the TTL would never get refreshed during
long tool executions. This caused the typing indicator to stop after
2 minutes even if tools were still running.
Now we refresh the TTL at the start of startTypingLoop, before the
early-return checks. This keeps typing alive during long operations.
- Default: sendAudio (file with metadata) - preserves old behavior
- Opt-in: [[audio_as_voice]] tag for voice bubble
This is non-breaking - existing integrations keep working.
Allow agents to specify audio mode via inline tag:
- Default: voice bubble (sendVoice)
- [[audio_as_file]]: audio file with metadata (sendAudio)
The tag is stripped from the final message text.
Example agent response:
Here's a podcast episode! [[audio_as_file]]
MEDIA:https://example.com/episode.mp3
When queued messages come from different providers (Slack + Telegram),
process them individually instead of collecting into a single prompt.
This ensures each reply routes back to its originating provider.
- Add hasCrossProviderItems() to detect multi-provider queues
- Skip collect mode when cross-provider detected
- Preserve originatingChannel/originatingTo when collecting same-provider
When OriginatingChannel matches Surface (same provider), use normal
dispatcher. Only route via routeReply() when they differ, ensuring
cross-provider messages (e.g., Telegram queued while Slack active)
get routed back to their origin.
Implement reply routing based on OriginatingChannel/OriginatingTo fields.
This ensures replies go back to the provider where the message originated
instead of using the session's lastChannel.
Changes:
- Add OriginatingChannel/OriginatingTo fields to MsgContext (templating.ts)
- Add originatingChannel/originatingTo fields to FollowupRun (queue.ts)
- Create route-reply.ts with provider-agnostic router
- Update all providers (Telegram, Slack, Discord, Signal, iMessage)
to pass originating channel info
- Update reply.ts to pass originating channel to followupRun
- Update followup-runner.ts to use route-reply for originating channels
This addresses the issue where messages from one provider (e.g., Slack)
would receive replies on a different provider (e.g., Telegram) because
the queue used the last active dispatcher instead of the originating one.
- Added `isError` property to `EmbeddedPiRunResult` and reply items to indicate error states.
- Updated error handling in `runReplyAgent` to provide more informative messages for specific socket connection errors.