fix(ai-sessions): restore a refused prompt's context and drop the stale idle entry

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
hugocasa
2026-08-28 11:35:39 +02:00
co-authored by Claude Opus 5
parent 2e83d582a6
commit e6f1137257
2 changed files with 17 additions and 4 deletions
@@ -1801,10 +1801,16 @@ export class AIChatManager {
// fall back on — the raw-app inline prompt would lose what the user
// typed outright. Not `restoreToInput`, whose no-composer fallback is
// the very queue being refused.
const restored = this.aiChatInput?.prependText(text, images, files) === true
if (restored) this.#restoreDomContext(context, true)
const composer = this.aiChatInput
if (composer) {
// `prependText` answers "did this land on top of a draft already being
// written", not "did it land at all" — it always restores. Its return
// is what tells #restoreDomContext whether to keep the existing chips
// as well as the restored ones.
this.#restoreDomContext(context, composer.prependText(text, images, files))
}
sendUserToast(
restored
composer
? 'This session is running in another tab. Your prompt is waiting in the composer.'
: 'This session is running in another tab. Try again when it finishes.',
true
@@ -98,7 +98,14 @@ export function noteDriverAlive(sessionId: string, planMode: boolean): void {
* the truthful position rather than merely the convenient one. */
export function noteRemoteTurnEnded(sessionId: string): void {
if (runPosition(sessionId).state !== 'watching') return
positions.set(sessionId, canCompleteCatchUp() ? { state: 'catchingUp' } : { state: 'idle' })
// Deleted rather than set to idle: a missing entry already reads as idle, and
// the tab this branch exists for has no runtime, so nothing in it would ever
// call clearRunPosition to take the entry back out again.
if (!canCompleteCatchUp()) {
positions.delete(sessionId)
return
}
positions.set(sessionId, { state: 'catchingUp' })
}
/** The re-read finished: this tab's transcript and history are one conversation