Skip to content

Unify runtime status shown across UIs#13376

Merged
dhruvisompura merged 14 commits into
mainfrom
feature/derive-runtime-status-from-session
May 18, 2026
Merged

Unify runtime status shown across UIs#13376
dhruvisompura merged 14 commits into
mainfrom
feature/derive-runtime-status-from-session

Conversation

@dhruvisompura
Copy link
Copy Markdown
Contributor

@dhruvisompura dhruvisompura commented May 5, 2026

Based off feedback from @seeM in #13045

Three places show runtime status — the console tab icon, the notebook session badge, and the Quarto session badge. Each had its own mapping chain to get from a runtime session's state to a display icon:

  • Console: PositronConsoleState -> RuntimeStatus
  • Notebook: RuntimeState -> KernelStatus -> RuntimeStatus
  • Quarto: RuntimeState -> QuartoKernelState -> RuntimeStatus

These mappings can easily drift to show different states and for a notebook user this can be odd/confusing since we show the runtime status icon in multiple places.

One visible fix from this change is in the console which previously would show the wrong state during restart compared to the interpreter picker.

NOTE: the interpreter picker can become out of sync with the notebook kernel badge and notebook console session when a user chooses the "Change Kernel" option. This is also the case for Quarto as well. I didn't attempt to resolve that here and this may be worth tackling instead when we try and unify the quarto/notebook UI.

I think that fix gets us one step closer to unifying the runtime statuses.

Screenshots

BEFORE - notebook restart

before.mov

AFTER - notebook restart

Screen.Recording.2026-05-05.at.6.40.29.PM.mov

BEFORE - console restart

before.console.mov

AFTER - console restart

TBD

Release Notes

New Features

  • N/A

Bug Fixes

  • N/A

Validation Steps

@:console @:positron-notebooks @:quarto @:sessions

@github-actions
Copy link
Copy Markdown

github-actions Bot commented May 5, 2026

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:console @:positron-notebooks @:quarto @:sessions

readme  valid tags

@dhruvisompura dhruvisompura marked this pull request as ready for review May 6, 2026 16:44
@dhruvisompura dhruvisompura requested a review from seeM May 6, 2026 16:44
Copy link
Copy Markdown
Contributor

@seeM seeM left a comment

Choose a reason for hiding this comment

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

Notebook and console runtime status icons look correct but Quarto restart has an additional "Starting" state with a disconnected status.

Screen.Recording.2026-05-07.at.15.59.57.mov

Comment thread src/vs/workbench/contrib/positronNotebook/browser/IPositronNotebookInstance.ts Outdated
// update the kernel status to the runtime session state
this.kernelStatus.set(KernelStatus.Starting, undefined);
}
if (newKernel && oldKernel) {
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.

There is a regression here. Previously, switching interpreters would show immediate UI feedback via the spinner. Now there's a delay.

Before:

Screen.Recording.2026-05-07.at.16.10.02.mov

After:

Screen.Recording.2026-05-07.at.16.09.35.mov

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

ah, thanks for catching!

return <div data-testid={'state'}>{state ?? 'none'}</div>;
};

describe('useSessionRuntimeState', () => {
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.

Nice 👌 I'm curious if you used the Claude skill here, and if so how much you had to intervene manually?

Copy link
Copy Markdown
Contributor Author

@dhruvisompura dhruvisompura May 7, 2026

Choose a reason for hiding this comment

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

yep, I used the skill here for all of the tests. It did a pretty decent job with the simpler tsx files. I did have to go and remove some tests that were testing the wrong thing or didn't make a lot of sense to me. It wasn't that much work to fix it though since most of the time its just removing tests.

Comment on lines +53 to +58
it('shows active icon during Restarting (regression: previously showed stale state via PositronConsoleState)', () => {
const { session, emitter } = makeSession(RuntimeState.Idle);
rtl.render(<ConsoleSessionStatusIcon positronConsoleInstance={makeInstance(session)} />);
act(() => emitter.fire(RuntimeState.Restarting));
expect(screen.getByTestId('runtime-status-active')).toBeInTheDocument();
});
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.

How about writing the test with the preferred behavior and using it.fails?

Comment thread src/vs/workbench/contrib/positronNotebook/browser/useNotebookRuntimeSession.tsx Outdated
Comment on lines +34 to 37
const quartoStateToRuntimeStatus: Partial<Record<QuartoKernelState, RuntimeStatus>> = {
[QuartoKernelState.None]: RuntimeStatus.Disconnected,
[QuartoKernelState.Starting]: RuntimeStatus.Active,
[QuartoKernelState.Ready]: RuntimeStatus.Idle,
[QuartoKernelState.Busy]: RuntimeStatus.Active,
[QuartoKernelState.Error]: RuntimeStatus.Disconnected,
[QuartoKernelState.ShuttingDown]: RuntimeStatus.Active,
};
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.

Nit: I think this would give a more accurate and helpful type - have not tested

Suggested change
const quartoStateToRuntimeStatus: Partial<Record<QuartoKernelState, RuntimeStatus>> = {
[QuartoKernelState.None]: RuntimeStatus.Disconnected,
[QuartoKernelState.Starting]: RuntimeStatus.Active,
[QuartoKernelState.Ready]: RuntimeStatus.Idle,
[QuartoKernelState.Busy]: RuntimeStatus.Active,
[QuartoKernelState.Error]: RuntimeStatus.Disconnected,
[QuartoKernelState.ShuttingDown]: RuntimeStatus.Active,
};
const quartoStateToRuntimeStatus = {
[QuartoKernelState.None]: RuntimeStatus.Disconnected,
[QuartoKernelState.Error]: RuntimeStatus.Disconnected,
} satisfies Partial<Record<QuartoKernelState, RuntimeStatus>>;

The `runOnChange(this.kernel, ...)` block only set Switching when both
oldKernel and newKernel were set, so first-time selection left
kernelStatus at Unselected and the badge briefly rendered Disconnected
with the kernel's runtime name. Make the badge show Active as soon as a
kernel is selected, rather than waiting for the session to attach.

Replace `useNotebookRuntimeSession` with a `runtimeSession` observable
on IPositronNotebookInstance. The hook duplicated session resolution
the model already does in `_maybeAttachSession` (initial lookup +
onWillStartSession + onDidEndSession). Mirrors the existing `kernel`
observable pattern.
Disambiguates the enum name, and replaces the `undefined` sentinel that
meant "session is attached" with an explicit `Connected` value so the
type is honest. `kernelStatus` is now `IObservable<NotebookKernelStatus>`
without the `| undefined` widening.
…tching

When a notebook foreground session is deleted during a kernel switch,
foregroundSessionDisplayInfo briefly surfaces the deleted session's
Exited state, which makes the interpreter picker flash Disconnected
before the new session takes foreground. The notebook badge avoids this
because it reads session state directly. Document the desired picker
behavior with `it.fails` so a future fix can deal with this
The badge prioritized live runtime state over kernelStatus, so when the
user picked a new kernel `kernelStatus = Switching` was set but the
old session was still Idle and won the display. The spinner only kicked
in once the old session started exiting -- a perceptible delay vs.
clicking. Add a Switching override at the top of the ladder so user
intent shows immediately, regardless of the old session's now-stale
state. _maybeAttachSession clears Switching when the new session
attaches, after which live runtime state takes over.
@dhruvisompura dhruvisompura requested a review from seeM May 7, 2026 20:23
seeM
seeM previously approved these changes May 11, 2026
Copy link
Copy Markdown
Contributor

@seeM seeM left a comment

Choose a reason for hiding this comment

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

Looks great! I noticed another issue but it's in release builds too so isn't a regression, might already be on your radar. Starting an exited notebook session behaves differently in the notebook kernel status and top interpreter picker

Screen.Recording.2026-05-11.at.13.05.20.mov

@dhruvisompura
Copy link
Copy Markdown
Contributor Author

Looks great! I noticed another issue but it's in release builds too so isn't a regression, might already be on your radar. Starting an exited notebook session behaves differently in the notebook kernel status and top interpreter picker

Screen.Recording.2026-05-11.at.13.05.20.mov

Ya, I noticed the same thing and it is on my radar. This has the same issue as switching kernels and the interpreter picker being out of sync with that.

@dhruvisompura dhruvisompura merged commit 0442939 into main May 18, 2026
23 checks passed
@dhruvisompura dhruvisompura deleted the feature/derive-runtime-status-from-session branch May 18, 2026 23:35
@github-actions github-actions Bot locked and limited conversation to collaborators May 18, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants