Skip to content

Preserve existing session origin when heartbeat/system events update an existing session #46116

Description

@kamiwang777

Summary

A heartbeat poll or other internal/system event can overwrite the persisted origin metadata of an existing session entry.

This is especially visible for stable sessions such as agent:kabot-core:main: after a heartbeat is delivered into that session, the session still keeps the same sessionKey, but its stored origin.label/from/to may become heartbeat, which then makes Control UI / session lists show the session as heartbeat.

Why this is a bug

origin appears to represent stable session identity/binding metadata, while heartbeat/system events are transient internal activity.

Allowing a later internal event to overwrite origin causes:

  • session identity drift
  • confusing Control UI labels
  • a main session appearing to “turn into” heartbeat even though the sessionKey did not change

Observed behavior

A persisted session entry for agent:kabot-core:main ended up with:

"origin": {
  "provider": "webchat",
  "surface": "webchat",
  "chatType": "direct",
  "label": "heartbeat",
  "from": "heartbeat",
  "to": "heartbeat"
}

while the session itself was still the original main session.

Likely cause

The session merge path seems to apply normal patch overwrite semantics to origin, effectively preserving:

{
  ...existing,
  ...patch
}

So if a later heartbeat/system patch contains origin, it replaces the previous stable value.

Expected behavior

For an existing session:

  • heartbeat / cron / system events should not overwrite persisted origin
  • origin should remain stable unless explicitly re-bound or intentionally replaced

Suggested fix

Either or both:

  1. Preserve existing.origin during session merge unless origin replacement is explicitly allowed
  2. Avoid passing heartbeat/system-event origin when patching an existing session entry

Defense-in-depth would be ideal.

Impact

This looks small at first, but it affects persisted session identity, not just display text.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    Priority

    None yet

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions