Skip to content

Make console session commands agent-invocable - #15138

Merged
dhruvisompura merged 1 commit into
mainfrom
dhruvi/agent-compatible-console
Aug 5, 2026
Merged

Make console session commands agent-invocable#15138
dhruvisompura merged 1 commit into
mainfrom
dhruvi/agent-compatible-console

Conversation

@dhruvisompura

@dhruvisompura dhruvisompura commented Jul 25, 2026

Copy link
Copy Markdown
Contributor

Addresses part of #15063.

Summary

Makes two console commands invocable by Posit Assistant:

  • workbench.action.language.runtime.startNewConsoleSession: gains a runtimeId argument. When supplied, the session starts headless (no runtime picker); an unknown id throws so positron.ai.validateAndExecuteCommand reports {ok: false} instead of silently succeeding. The anonymous action class is promoted to an exported StartNewConsoleSessionAction for testability.
  • workbench.action.language.runtime.selectSession: same treatment with a sessionId argument (SelectSessionAction), converted off the shared registerLanguageRuntimeAction helper so it can carry arg metadata. An id naming a session that has exited throws too, because the session picker already leaves exited sessions out and selecting one by id shouldn't get around that.

Both commands only show interactive pickers if a runtimeId/sessionId is not provided which lets us programmatically execute the command without interruption. If the id is omitted the picker still opens and waits on the user, and the command has no way to tell an agent caller from a human one (nothing in ICommandService carries the caller, and validateAndExecute is deliberately not a policy gate -- see posit-dev/assistant#1810). So the id is declared required in the agent metadata that positron.ai.getAgentAllowedCommands() reports, while the argument stays optional in code to keep the palette, keybinding, and menu paths working.

Both commands also report their outcome as data now: startNewConsoleSession returns {started, sessionId, message} and selectSession returns {selected, sessionId, message}. Without this, a picker the user dismissed reached Assistant as Ran '<command id>'., which reads as success even though nothing happened. startNewConsoleSession used to return a bare session id string, so selectLanguageRuntimeSession now reads sessionId off the result -- that's the "New Console Session..." item inside the Select Session picker.

MAJOR GAP

This PR only updates the commands to be non-interactive but doesn't make them usable by Assistant without some additional context.

Posit Assistant does not currently have a way to learn what a valid runtimeId/sessionId value is. These are currently internal values within Positron. The initial plan was to leverage getRegisteredRuntimes() to create a mapping of runtimes to their IDs for workbench.action.language.runtime.startNewConsoleSession and provide that context alongside the system prompt. I was going to do something similar for workbench.action.language.runtime.selectSession.

Given that we want to move away from putting context in the system prompt, we need to provide this context some other way. We can't add new tools to Assistant, so the stepping stone is still two commands (getRuntimeIds, getSessionIds) that Assistant can run through positronCommand to get the information it needs, reading getRegisteredRuntimes() and activeSessions on the Positron side. We document all four commands in the same reference file and tell Assistant how to use them together. Tracking that in #15346.

One lookup fewer than planned: startNewConsoleSession now returns the new sessionId, so starting a session and then making it active doesn't need getSessionIds at all. And getSessionIds can filter with the isActiveSessionState helper this PR extracts, so the sessions it lists are exactly the ones selectSession will accept.

Screenshots

Took some videos to show that the existing behavior has not changed

15138-switchSession.mp4
15138-startSession.mp4
15138-newSessionFromPicker.mp4
15138-dismissPickers.mp4

Release Notes

New Features

Bug Fixes

  • N/A

Validation Steps

@:console @:sessions

Verify user behavior is unchanged

  1. From the palette run "Start New Console Session" and verify a picker opens for the user to select a runtime. Pick one and verify the session starts.
  2. Run it again and dismiss the picker with Esc. Verify nothing starts and no error notification appears.
  3. From the palette run "Select Session" and verify a picker opens for the user to select a session. Pick one and verify it becomes the active session.
  4. Run "Select Session" again and choose "New Console Session...". Verify the runtime picker opens and the session you pick starts and becomes active. (This path reads the new return value.)
  5. With no console sessions running, verify the + button in the Console pane title bar still opens the runtime picker.

Verify the commands are advertised to Assistant

  1. Run "Developer: Show Agent-Allowed Commands" and verify both workbench.action.language.runtime.startNewConsoleSession and workbench.action.language.runtime.selectSession appear, each with its args entry (required: true, type: "string") and a returns description.

Verify the non-interactive path

SETUP: get a real runtimeId and sessionId for an existing session via the Runtimes debug panel (enable interpreters.showSessions setting to see it). The ID field in the table is the session ID.

image
  1. Add temporary keybindings.json entries and press each key. Verify the session starts / becomes active with no picker opening:
{ "key": "cmd+1", "command": "workbench.action.language.runtime.startNewConsoleSession", "args": "<runtimeId>" },
{ "key": "cmd+2", "command": "workbench.action.language.runtime.selectSession", "args": "<sessionId>" }
  1. Change both args values to "does-not-exist" and press each key again. Verify each one fails with an error instead of opening a picker (a keybinding surfaces the thrown message as a warning notification).
  2. Shut down a console session, then set the selectSession binding's args to that exited session's id. Verify it fails with Session '<id>' has exited and cannot be made the active session. and the active session does not change.

@github-actions

Copy link
Copy Markdown

E2E Tests 🚀
This PR will run tests tagged with: @:critical @:console @:sessions @:interpreter

Why these tags?
Tag Source
@:critical Always runs (required)
@:console PR description
@:sessions PR description
@:interpreter Changed files

More on automatic tags from changed files.

readme  valid tags

@github-actions github-actions Bot locked and limited conversation to collaborators Jul 28, 2026
@dhruvisompura dhruvisompura reopened this Aug 4, 2026
Give the Start New Console Session and Select Session commands an optional
id argument so they can run without any user interaction, and report their
outcome as data so a programmatic caller can tell a real change apart from a
picker the user dismissed.

- startNewConsoleSession takes a runtimeId and returns
  { started, sessionId, message }; selectSession takes a sessionId and
  returns { selected, sessionId, message }.
- A supplied id that names no runtime or session, or names a session that
  has exited, throws instead of falling back to the picker, which would
  leave a programmatic caller waiting on the user.
- The exited-session check reuses the state filter the session picker
  already applies, extracted as isActiveSessionState.
- Both commands still open their picker when no id is supplied, so the
  command palette, keybinding, and menu paths are unchanged.
- Promote both anonymous action classes to exported StartNewConsoleSessionAction
  and SelectSessionAction for testability, and move selectSession off the
  shared registerLanguageRuntimeAction helper so it can carry arg metadata.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@dhruvisompura
dhruvisompura force-pushed the dhruvi/agent-compatible-console branch from 27a51d7 to b860504 Compare August 4, 2026 22:59
@dhruvisompura
dhruvisompura marked this pull request as ready for review August 5, 2026 00:41
@dhruvisompura
dhruvisompura requested a review from midleman August 5, 2026 00:41
@posit-dev posit-dev unlocked this conversation Aug 5, 2026

@midleman midleman 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.

Looks good! I played with it quite a bit and it seems to be working quite well. :) Some scenarios I tested:

  • starting console session via command
  • switching console session via command
  • switching to notebook session via command (this was cool, it switches focus to the notebook tab and the console session tab)
  • starting notebook runtime via command
  • commands working post window reload
  • commands working post session restart

@dhruvisompura
dhruvisompura merged commit 93db136 into main Aug 5, 2026
26 of 32 checks passed
@dhruvisompura
dhruvisompura deleted the dhruvi/agent-compatible-console branch August 5, 2026 16:40
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 5, 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