fix(gateway): re-inject topic-bound skill after /new or /reset
reset_session() creates a fresh SessionEntry with created_at == updated_at, but get_or_create_session() bumps updated_at on the next inbound message, causing _is_new_session in _handle_message_with_agent to evaluate False. The topic/channel skill auto-load gate (group_topics, channel_skill_bindings) silently skips the first message after a manual reset. Add an is_fresh_reset flag on SessionEntry, set by reset_session() and consumed once by the message handler. Kept distinct from was_auto_reset because that flag also drives a 'session expired due to inactivity' user-facing notice and a context-note prepend — both wrong for an explicit /new or /reset. Persisted through to_dict/from_dict so the flag survives gateway restart between /reset and the next message. Fixes #6508 Co-authored-by: warabe1122 <45554392+warabe1122@users.noreply.github.com> Co-authored-by: willy-scr <187001140+willy-scr@users.noreply.github.com>
This commit is contained in:
@@ -5300,7 +5300,12 @@ class GatewayRunner:
|
||||
_is_new_session = (
|
||||
session_entry.created_at == session_entry.updated_at
|
||||
or getattr(session_entry, "was_auto_reset", False)
|
||||
or getattr(session_entry, "is_fresh_reset", False)
|
||||
)
|
||||
# Consume the is_fresh_reset flag immediately so it doesn't leak
|
||||
# onto subsequent messages in the same session (issue #6508).
|
||||
if getattr(session_entry, "is_fresh_reset", False):
|
||||
session_entry.is_fresh_reset = False
|
||||
if _is_new_session:
|
||||
await self.hooks.emit("session:start", {
|
||||
"platform": source.platform.value if source.platform else "",
|
||||
|
||||
@@ -458,6 +458,15 @@ class SessionEntry:
|
||||
was_auto_reset: bool = False
|
||||
auto_reset_reason: Optional[str] = None # "idle" or "daily"
|
||||
reset_had_activity: bool = False # whether the expired session had any messages
|
||||
|
||||
# Set by reset_session() when the user explicitly sends /new or /reset.
|
||||
# Consumed once by _handle_message_with_agent to trigger topic/channel
|
||||
# skill re-injection on the first message of the new session. We can't
|
||||
# reuse was_auto_reset for this because that flag fires the "session
|
||||
# expired due to inactivity" user-facing notice and a misleading
|
||||
# context-note prepend — both wrong for an explicit manual reset.
|
||||
# See issue #6508.
|
||||
is_fresh_reset: bool = False
|
||||
|
||||
# Set by the background expiry watcher after it finalizes an expired
|
||||
# session (invoking on_session_finalize hooks and evicting the cached
|
||||
@@ -508,6 +517,7 @@ class SessionEntry:
|
||||
if self.last_resume_marked_at
|
||||
else None
|
||||
),
|
||||
"is_fresh_reset": self.is_fresh_reset,
|
||||
}
|
||||
if self.origin:
|
||||
result["origin"] = self.origin.to_dict()
|
||||
@@ -556,6 +566,7 @@ class SessionEntry:
|
||||
resume_pending=data.get("resume_pending", False),
|
||||
resume_reason=data.get("resume_reason"),
|
||||
last_resume_marked_at=last_resume_marked_at,
|
||||
is_fresh_reset=data.get("is_fresh_reset", False),
|
||||
)
|
||||
|
||||
|
||||
@@ -1132,6 +1143,7 @@ class SessionStore:
|
||||
display_name=old_entry.display_name,
|
||||
platform=old_entry.platform,
|
||||
chat_type=old_entry.chat_type,
|
||||
is_fresh_reset=True,
|
||||
)
|
||||
|
||||
self._entries[session_key] = new_entry
|
||||
|
||||
Reference in New Issue
Block a user