Skip to content

fix(desktop): keep queued prompts bound to their sessions - #66929

Closed
iwillwill-ALLWILL wants to merge 1 commit into
NousResearch:mainfrom
iwillwill-ALLWILL:fix/background-queue-null-session-routing
Closed

fix(desktop): keep queued prompts bound to their sessions#66929
iwillwill-ALLWILL wants to merge 1 commit into
NousResearch:mainfrom
iwillwill-ALLWILL:fix/background-queue-null-session-routing

Conversation

@iwillwill-ALLWILL

Copy link
Copy Markdown

Bug Description

When one Desktop session is running, sending a queued prompt from another conversation can route the prompt back to the running foreground conversation and navigate the UI there. Restarting Desktop clears the transient queue/runtime state and temporarily restores normal behavior.

Root Cause

The background queue drain deliberately passes sessionId: null when its stored session has no live runtime mapping. submitText used nullish coalescing and later falsy route-recovery checks, so that authoritative null was replaced with the foreground runtime/session context.

Background drains could also outlive a profile switch, but queue entries did not persist their owner profile and all submit RPCs used the active gateway.

Fix

  • Treat an explicit null runtime target as authoritative: resume the queued stored session instead of inheriting the foreground runtime.
  • Keep foreground route recovery exclusive to submits that omit sessionId.
  • Persist the owning profile on queued prompts and propagate stored/runtime/profile targets through both composer and background drains.
  • Route resume, attachment staging, and prompt submission through the owner profile's gateway without changing the active profile.
  • Preserve the queued profile across localStorage and use the session-list lookup only as a backward-compatible fallback for old queue entries.

How to Verify

  1. Start a turn in foreground session A.
  2. Queue a prompt for session B, then make A the selected/routed session before B drains.
  3. Remove B's live runtime mapping and allow the background drain to run.
  4. Confirm Desktop resumes B on B's profile gateway, submits to the recovered B runtime, and leaves A selected and untouched.

Test Plan

  • Added regression coverage for explicit-null session targeting with a stale foreground route.
  • Added cross-profile gateway isolation assertions (foreground gateway is never called).
  • Added owner-profile persistence and drain propagation coverage.
  • Full Desktop UI suite: 175 files, 1426 tests passed.
  • TypeScript renderer and Electron configurations passed.
  • Production Desktop build passed.
  • ESLint, Prettier, and git diff --check passed.
  • Isolated packaged Electron startup canary passed.

Risk Assessment

Medium — the change touches queue metadata and profile-aware gateway selection, but retains the existing active-gateway path when no owner profile is supplied. Old persisted queue entries remain compatible through the existing session-list profile lookup.

@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) P2 Medium — degraded but workaround exists needs-decision Awaiting maintainer decision before any implementation sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 18, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #62203 and #56444's queued-prompt session binding work. This branch additionally preserves profile ownership and routes all queue-drain work through the owner profile's gateway, so it is competing/superset work rather than a duplicate.

@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused session-binding fix. The current-main defect is real: use-background-queue-drain.ts:115-123 supplies an explicit null runtime ID, while submit.ts:152 replaces it with activeSessionIdRef.current.

Problems

  • The owner profile is not persisted for every producer. apps/desktop/src/app/chat/composer/hooks/use-composer-submit.ts:189-193 enqueues a rejected /steer fallback without a profile. This PR adds profile persistence through useComposerQueue, but does not touch that producer. Such an entry still depends on the session-list fallback and can fall back to the active gateway when that lookup cannot resolve its owner.

Suggested changes

  • Thread queueProfile into useComposerSubmit and pass it to the enqueue at use-composer-submit.ts:191.
  • Cover the rejected-steer enqueue path followed by a cross-profile background drain; assert the foreground gateway is not called.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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 19, 2026
@OutThisLife

Copy link
Copy Markdown
Collaborator

Closing as superseded by #66001 (merged). Same fix surface (composer queue + background drain + submit targeting) for binding queued Desktop prompts to their originating session so they don't execute in / navigate to an unrelated busy conversation.

@teknium1 teknium1 added the area/sessions Session lifecycle, resume, persistence, history label Jul 19, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/sessions Session lifecycle, resume, persistence, history comp/desktop Electron desktop app (apps/desktop/*) needs-decision Awaiting maintainer decision before any implementation P2 Medium — degraded but workaround exists 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-message-delivery Sweeper risk: may drop, duplicate, misroute, or suppress messages 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.

4 participants