Skip to content

fix(desktop): scope messaging sessions by profile - #44157

Closed
protas-box wants to merge 1 commit into
NousResearch:mainfrom
protas-box:codex/fix-messaging-profile-scope
Closed

fix(desktop): scope messaging sessions by profile#44157
protas-box wants to merge 1 commit into
NousResearch:mainfrom
protas-box:codex/fix-messaging-profile-scope

Conversation

@protas-box

Copy link
Copy Markdown
Contributor

Summary

Fixes profile routing for messaging-source sessions in the Desktop sidebar.

In multi-profile/global-remote setups, messaging sessions were fetched with profile=all regardless of the active profile. That made Telegram/other messaging sessions from one profile appear under another profile's sidebar section.

Clicking one of those messaging rows could also fail to open the transcript because resumeSession() only resolved the owning profile from the regular recents list ($sessions). Messaging rows live in $messagingSessions, so their profile was dropped before ensureGatewayProfile(), getSessionMessages(), and session.resume.

Changes

  • Scope the messaging sidebar fetch and per-platform "load more" fetch to the active profile, matching the regular recents list behavior.
  • Keep all behavior when the sidebar is explicitly in all-profiles mode.
  • Include profile, source, and last_active in the messaging/cron section signature so profile/source changes update the atom instead of keeping stale rows.
  • Resolve the session owner from $messagingSessions and $cronSessions as fallbacks before resuming a stored session.

Validation

  • npm run typecheck --workspace apps/desktop
  • Manual validation with a remote Hermes backend serving multiple profiles:
    • Telegram sessions created under profile pm no longer appear in the default profile messaging section.
    • The same Telegram sessions open correctly from the pm profile and hydrate the stored transcript.

@alt-glitch alt-glitch added type/bug Something isn't working P3 Low — cosmetic, nice to have labels Jun 11, 2026

@tonydwb tonydwb left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review: PR #44157

Verdict: Approved — correct profile scoping fix for messaging sessions.

Summary

  • Files changed: apps/desktop/src/app/desktop-controller.tsx (+30, -10), apps/desktop/src/app/session/hooks/use-session-actions.ts (+6, -1)
  • Scopes messaging sidebar fetch and load-more to the active profile instead of always using 'all'
  • Includes profile, source, and last_active in section signature for proper stale-detection
  • Resolves session owner from messagingSessions and cronSessions as fallbacks

Assessment

Correctness: The fallback chain sessions -> messagingSessions -> cronSessions ensures session owner is found regardless of which list the session lives in.

No issues found.


Reviewed by Hermes Agent

@protas-box
protas-box force-pushed the codex/fix-messaging-profile-scope branch from 68561fa to fb1e5f9 Compare June 15, 2026 06:06
gitzwz added a commit to gitzwz/hermes-agent that referenced this pull request Jun 25, 2026
Cherry-pick of upstream PR NousResearch#44157 (fix profile routing for messaging
sessions in the Desktop sidebar). Resolve session owners from
messagingSessions and cronSessions before resuming stored sessions.

Fork-Origin: gitzwz
Cherry-Picked-From: NousResearch#44157
Co-Authored-By: Codex <noreply@openai.com>

@teknium1 teknium1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for tracing both the sidebar fetch and resume-owner paths. The underlying bug still exists on current main, but this branch needs a targeted port before it is safe to salvage.

Problems

  • The production fetches were extracted by 25c7900fb into apps/desktop/src/app/session/hooks/use-session-list-actions.ts; current refreshMessagingSessions and loadMoreMessagingForPlatform still hardcode profile="all" at lines 102 and 126, while refreshCronSessions has the same sibling defect at line 86.
  • The current regular-recents path guards stale async responses with refreshSessionsRequestRef at use-session-list-actions.ts:155-188. The proposed messaging scope change has no equivalent guard, so a result begun before a profile switch can publish old-profile rows afterward.
  • Current resolveStoredSession is now apps/desktop/src/app/session/hooks/use-session-actions/utils.ts:208; it still searches only $sessions, so the proposed messaging/cron fallback should be ported there.

Suggested changes

  • Rework the patch at those current locations, scope cron too, and add per-operation request-generation guards.
  • Add tests for active-profile and all-profiles fetches, messaging/cron owner resolution, and stale-result suppression.

Automated hermes-sweeper review.

const refreshMessagingSessions = useCallback(async () => {
try {
const result = await listAllProfileSessions(MESSAGING_SECTION_LIMIT, 1, 'exclude', 'recent', 'all', {
const sessionProfile = profileScope === ALL_PROFILES ? 'all' : profileScope

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please guard this async profile-scoped fetch with a request generation counter before publishing rows. If the user switches profiles while this request is in flight, its late result can overwrite the new profile's messaging section; current main's regular-recents refresh already uses this pattern.

@teknium1 teknium1 added sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform labels Jul 14, 2026
@teknium1 teknium1 added area/sessions Session lifecycle, resume, persistence, history area/profiles Multi-profile isolation, HERMES_HOME scoping labels Jul 19, 2026
@yewangmu

Copy link
Copy Markdown

Current-main port validation for messaging/cron cache resolution

I hit the second symptom described by this PR on current Desktop: clicking a row already present in $messagingSessions caused resolveStoredSession() to miss the cache, fetch by ID, and insert the same row into $sessions, so one conversation rendered in both sidebar sections.

The current location is now:

apps/desktop/src/app/session/hooks/use-session-actions/utils.ts

A minimal current-main port is to resolve from regular, cron, and messaging caches before performing by-ID lookup:

const cached = [...$sessions.get(), ...$cronSessions.get(), ...$messagingSessions.get()].find(session =>
  sessionMatchesStoredId(session, storedSessionId)
)

I added a focused regression in:

apps/desktop/src/app/session/hooks/use-session-actions/resolve-stored-session.test.ts

The test seeds a Telegram row only in $messagingSessions, calls resolveStoredSession(), and verifies:

  • the exact cached row is returned;
  • getSession() is not called;
  • $sessions stays empty.

TDD evidence: the new test failed on current main because the resolver returned undefined, then passed after the cache fallback was ported.

Validation on current origin/main (Windows 11):

  • targeted tests passed;
  • npm run typecheck passed;
  • npm run lint passed with 0 errors (existing warnings only);
  • full UI suite passed: 414 files, 3695 tests;
  • git diff --check passed;
  • local Electron candidate was exercised with live LINE/Telegram/Discord/WeChat sessions; selecting messaging rows no longer duplicated them into generic Sessions.

I have not opened a competing PR because this PR already contains the same underlying fallback on the pre-refactor file. I can provide the two-file current-main port as an incremental patch if useful.

@teknium1

Copy link
Copy Markdown
Contributor

Resolved on main by #87566, which consolidated this PR's fix with your Co-authored-by credit preserved in the merged commits. Thank you!

@teknium1 teknium1 closed this Aug 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/profiles Multi-profile isolation, HERMES_HOME scoping area/sessions Session lifecycle, resume, persistence, history P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants