Summary
The heartbeat configuration supports target, to, and accountId for delivery targeting, but to does not parse :topic:NNN suffix. When topics are enabled, heartbeat messages land in the last active topic (whichever thread had the most recent conversation) instead of a specific configured topic. This pollutes unrelated topics with heartbeat messages.
Proposed solution
Parse :topic:NNN suffix from explicitTo in the shared resolveSessionDeliveryTarget() resolver:
- When
explicitTo contains :topic:, use parseTelegramTarget() to extract chatId and messageThreadId
- Pass extracted
threadId through the existing explicitThreadId path
- This benefits all callers: heartbeat, cron delivery, agent delivery
Config example:
{
"agents": {
"defaults": {
"heartbeat": {
"target": "telegram",
"to": "-100123456:topic:42"
}
}
}
}
No new config fields needed — reuses existing to with standard Telegram topic syntax.
Alternatives considered
- Separate
threadId field in heartbeat config — works but adds unnecessary API surface; :topic: syntax already used elsewhere in the codebase
- Relying on session
lastThreadId — only works when last interaction was in the target topic, so heartbeat ends up in random topics depending on where the last conversation happened
Codebase and GitHub Search
parseTelegramTarget already used in message-action-runner.ts and outbound-session.ts
explicitThreadId param already exists in resolveSessionDeliveryTarget (used by agent-delivery.ts)
- No existing issue/PR for heartbeat topic support
Additional context
Companion to cron thread delivery bug fix (#19365). Together they ensure both scheduled jobs and heartbeats can target a specific Telegram topic instead of polluting the last active one.
lobster-biscuit
Summary
The heartbeat configuration supports
target,to, andaccountIdfor delivery targeting, buttodoes not parse:topic:NNNsuffix. When topics are enabled, heartbeat messages land in the last active topic (whichever thread had the most recent conversation) instead of a specific configured topic. This pollutes unrelated topics with heartbeat messages.Proposed solution
Parse
:topic:NNNsuffix fromexplicitToin the sharedresolveSessionDeliveryTarget()resolver:explicitTocontains:topic:, useparseTelegramTarget()to extractchatIdandmessageThreadIdthreadIdthrough the existingexplicitThreadIdpathConfig example:
{ "agents": { "defaults": { "heartbeat": { "target": "telegram", "to": "-100123456:topic:42" } } } }No new config fields needed — reuses existing
towith standard Telegram topic syntax.Alternatives considered
threadIdfield in heartbeat config — works but adds unnecessary API surface;:topic:syntax already used elsewhere in the codebaselastThreadId— only works when last interaction was in the target topic, so heartbeat ends up in random topics depending on where the last conversation happenedCodebase and GitHub Search
parseTelegramTargetalready used inmessage-action-runner.tsandoutbound-session.tsexplicitThreadIdparam already exists inresolveSessionDeliveryTarget(used byagent-delivery.ts)Additional context
Companion to cron thread delivery bug fix (#19365). Together they ensure both scheduled jobs and heartbeats can target a specific Telegram topic instead of polluting the last active one.
lobster-biscuit