fix(heartbeat): inject delivered messages into channel session for reply continuity

When heartbeat delivers output to a channel (e.g. Telegram), the message
is a raw OutboundMessage that bypasses the channel's session. If the user
replies, their reply enters a different session with no context about the
heartbeat message, so the agent cannot follow through.

This change injects the delivered heartbeat message as an assistant turn
into the target channel's session before publishing the outbound. When
the user replies, the channel session has conversational context.

Handles unified_session mode by resolving to UNIFIED_SESSION_KEY when
enabled, matching the agent loop's own session routing.

No changes to agent/loop.py, session/manager.py, channels, providers,
or config schema — uses existing add_message() and save() APIs.
This commit is contained in:
hussein1362
2026-04-26 20:08:21 +08:00
committed by Xubin Ren
parent 1e11b35b45
commit 1572626100
2 changed files with 123 additions and 1 deletions
+21 -1
View File
@@ -812,11 +812,31 @@ def _run_gateway(
return resp.content if resp else ""
async def on_heartbeat_notify(response: str) -> None:
"""Deliver a heartbeat response to the user's channel."""
"""Deliver a heartbeat response to the user's channel.
In addition to publishing the outbound message, this injects the
delivered text as an assistant turn into the *target channel's*
session. Without this, a user reply on the channel (e.g. "Sure")
lands in a session that has no context about the heartbeat message
and the agent cannot follow through.
"""
from nanobot.bus.events import OutboundMessage
channel, chat_id = _pick_heartbeat_target()
if channel == "cli":
return # No external channel available to deliver to
# Inject the delivered message into the channel session so that
# user replies have conversational context.
from nanobot.agent.loop import UNIFIED_SESSION_KEY
target_key = (
UNIFIED_SESSION_KEY
if config.agents.defaults.unified_session
else f"{channel}:{chat_id}"
)
target_session = agent.sessions.get_or_create(target_key)
target_session.add_message("assistant", response)
agent.sessions.save(target_session)
await bus.publish_outbound(OutboundMessage(channel=channel, chat_id=chat_id, content=response))
hb_cfg = config.gateway.heartbeat