* fix(bluebubbles): debounce by messageId to preserve attachments in text+image messages
BlueBubbles fires multiple webhook events for a single message - first
without attachment metadata, then ~350ms later with it. Previously,
messages with attachments bypassed debouncing and were processed
immediately, while the text-only version was also queued.
Now the debouncer uses messageId as the key when available, coalescing
all webhook events for the same message. The existing combineDebounceEntries
function merges attachments from all events.
Closes#4848
* fix: increase debounce and handle balloon messages
- Increase DEFAULT_INBOUND_DEBOUNCE_MS from 350ms to 500ms
- Update buildKey to use associatedMessageGuid for balloon messages
- Add regression test for debouncing behavior
Fixes issues identified in code review.
---------
Co-authored-by: Yurii Chukhlib <yurii.chukhlib@viber.com>
Co-authored-by: Tyler Yust <TYTYYUST@YAHOO.COM>
* fix: prefer requesterOrigin over stale session entry in subagent announce routing
When a subagent finishes and announces results back, resolveAnnounceOrigin
merged the session entry (primary) with requesterOrigin (fallback). If the
session store had a stale lastChannel (e.g. whatsapp) from a previous
interaction but the user was now on a different channel (e.g. bluebubbles),
the announce would route to the wrong channel.
Swap the merge order so requesterOrigin (captured at spawn time, reflecting
the actual current channel) takes priority, with the session entry as
fallback for any missing fields.
Error before fix:
Delivery failed (whatsapp to bluebubbles:chat_guid:...): Unknown channel: whatsapp
Adds regression test for the stale-channel scenario.
* fix: match test to exact failure scenario and improve reliability (#4957) (thanks @tyler6204)
- Remove lastTo from stale session store to match the exact mismatch scenario described in the PR
- Replace 5ms setTimeout sleeps with expect.poll for better test reliability
- Prevents flakiness on slower CI machines
What: swap sessions_list for agents_list in /tools/invoke tests
Why: avoid nested gateway calls that can hang under CI; still validates tool invocation + allowlist
Tests: not run (CI should cover)
OAuth credentials with a refresh token auto-renew on first API call,
so the doctor should not warn about access token expiration when a
refresh token is present. This avoids unnecessary "expired" warnings
that prompt users to re-auth when no action is needed.
Fixes#3032
Co-authored-by: Ayush Ojha <ayushozha@outlook.com>
Unify style and link closing in render.ts to use LIFO order across
both element types, fixing cases where bold/italic spans containing
autolinks produced invalid HTML like <b><a></b></a>.
The react action used readStringParam for messageId and chatId, which
rejected numeric values with a misleading "messageId required" error.
Switched to readStringOrNumberParam to match the delete/edit actions.
Closes#1459
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fixes#4038
The global fetch in Node.js doesn't support undici's dispatcher option,
which is required for ProxyAgent to work. This fix imports fetch from
undici directly to enable proper proxy support for Telegram API calls.
Root cause: makeProxyFetch() was using global fetch with { dispatcher: agent },
but Node.js's global fetch ignores the dispatcher option. Using undici.fetch
ensures the ProxyAgent dispatcher is properly respected.
Tested: Build passes, TypeScript compilation successful.
registerTelegramNativeCommands() calls listSkillCommandsForAgents()
without passing agentIds, causing ALL agents' skill commands to be
registered on EVERY Telegram bot. When multiple agents share skill
names (e.g. two agents both have a "butler" skill), the shared `used`
Set in listSkillCommandsForAgents causes de-duplication suffixes
(_2, _3) and all commands appear on every bot regardless of agent
binding.
This fix uses the existing resolveAgentRoute() (already imported) to
find the bound agent for the current Telegram accountId, then passes
that agentId to listSkillCommandsForAgents(). The function already
accepts an optional agentIds parameter — it just wasn't wired from
the Telegram registration path.
Before: All agents' skill commands registered on every Telegram bot,
causing /butler_2, /housekeeper_2 dedup suffixes and potential
BOT_COMMANDS_TOO_MUCH errors when total exceeds 100.
After: Each Telegram bot only registers skill commands for its own
bound agent. No cross-agent dedup, no command limit overflow.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
* feat: add Kimi K2.5 model to synthetic catalog
Add hf:moonshotai/Kimi-K2.5 to the synthetic model catalog.
This model is available via dev.synthetic.new API.
- 256k context window
- 8192 max tokens
- Supports reasoning
* chore: fix formatting in onboard-helpers.ts
* fix: update config candidate ordering test (#4407) (thanks @manikv12)
---------
Co-authored-by: Peter Steinberger <steipete@gmail.com>
Replaced the static image with a responsive logo using the <picture> element for light/dark mode support. Updated contributor name from 'Clawd' to 'Molty'.