Skip to content

Conversation

nstrayer
Copy link
Contributor

@nstrayer nstrayer commented Jun 25, 2025

Addresses #8174.

Adds a new installPythonPackage tool that enables the Assistant to directly install Python packages instead of suggesting !pip commands that don't work in Positron's environment. The Assistant can now handle package installation requests by invoking the appropriate package manager (pip, uv, conda) through the integrated tool.

Note: This may be way too intense of a fix for a simple behavior change. Not at all married to the whole new tool at all.

Release Notes

New Features

  • N/A

Bug Fixes

  • Assistant can now directly install Python packages instead of suggesting non-functional
    !pip commands

QA Notes

Ask the Assistant to install Python packages like palmerpenguins and plotnine. The Assistant should now use the built-in installation tool rather than suggesting !pip commands.

Test in assistant

# Ask: "Install palmerpenguins and plotnine for me"
# Expected: Assistant uses the installPythonPackage tool to install packages directly
# Packages should be installed successfully without user needing to run terminal commands

The Assistant should no longer suggest !pip install commands and instead handle package installation automatically using the new tool.

Copy link

github-actions bot commented Jun 25, 2025

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

readme  valid tags

Copilot

This comment was marked as outdated.

@nstrayer nstrayer marked this pull request as draft June 25, 2025 16:29
@nstrayer nstrayer marked this pull request as ready for review June 25, 2025 17:16
Copy link
Collaborator

@jmcphers jmcphers left a comment

Choose a reason for hiding this comment

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

This did not work for me locally.

image

This is a Python 3.11 environment with uv venv. Would you expect that to work?

@nstrayer
Copy link
Contributor Author

Weird. I tested it with uv and python 3.12. Alas. I'll look into it tomorrow!

@nstrayer
Copy link
Contributor Author

image I can't reproduce.

@nstrayer nstrayer force-pushed the smarter-assistant-python-pkg-install branch from 53eb338 to bd39897 Compare June 26, 2025 16:10
@nstrayer nstrayer requested review from Copilot and wch June 26, 2025 16:10
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR enables the Assistant to install Python packages directly by introducing a new command handler in the Positron Python extension and wiring it up as an Assistant tool instead of relying on !pip suggestions.

  • Adds InstallPackagesCommandHandler to handle python.installPackages in Positron Python.
  • Registers a new installPythonPackage tool in the Assistant that invokes this command.
  • Updates prompts, types, and metadata to guide the Assistant to use the new workflow.

Reviewed Changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
extensions/positron-python/src/client/common/serviceRegistry.ts Import and register InstallPackagesCommandHandler
extensions/positron-python/src/client/common/constants.ts Added InstallPackages command constant
extensions/positron-python/src/client/common/application/commands/installPackages.ts Implemented InstallPackagesCommandHandler
extensions/positron-python/src/client/common/application/commands.ts Mapped Commands.InstallPackages to [string[]] args
extensions/positron-python/package.json Added “Install Python Packages” command entry
extensions/positron-assistant/src/types.ts Defined InstallPythonPackage tool name
extensions/positron-assistant/src/tools.ts Registered installPythonPackage tool
extensions/positron-assistant/src/md/prompts/chat/instructions-python.md Added Python package installation rules and examples
extensions/positron-assistant/package.json Declared metadata for installPythonPackage tool
Comments suppressed due to low confidence (2)

extensions/positron-python/src/client/common/application/commands/installPackages.ts:14

  • Add a class-level JSDoc comment for InstallPackagesCommandHandler to explain its purpose and activation behavior.
@injectable()

extensions/positron-python/src/client/common/application/commands/installPackages.ts:1

  • No unit tests have been added for InstallPackagesCommandHandler; consider adding tests covering input validation, installer absence, and success/failure flows.
/*---------------------------------------------------------------------------------------------

Comment on lines 62 to 74
for (const packageName of packages) {
try {
await installer.installModule(packageName, undefined, undefined, ModuleInstallFlags.none, undefined);
results.push(`${packageName} installed successfully using ${installer.displayName}`);
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
results.push(`${packageName}: Installation failed - ${errorMsg}`);
// Continue with next package to provide complete installation report
}
}

Copy link
Preview

Copilot AI Jun 26, 2025

Choose a reason for hiding this comment

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

[nitpick] Installing packages sequentially can be slow for multiple items; consider running installs in parallel (e.g., with Promise.all) and aggregating results.

Suggested change
for (const packageName of packages) {
try {
await installer.installModule(packageName, undefined, undefined, ModuleInstallFlags.none, undefined);
results.push(`${packageName} installed successfully using ${installer.displayName}`);
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
results.push(`${packageName}: Installation failed - ${errorMsg}`);
// Continue with next package to provide complete installation report
}
}
const installationPromises = packages.map(async (packageName) => {
try {
await installer.installModule(packageName, undefined, undefined, ModuleInstallFlags.none, undefined);
return `${packageName} installed successfully using ${installer.displayName}`;
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error);
return `${packageName}: Installation failed - ${errorMsg}`;
}
});
const settledResults = await Promise.allSettled(installationPromises);
results.push(...settledResults.map((result) => (result.status === 'fulfilled' ? result.value : '')));

Copilot uses AI. Check for mistakes.

jmcphers
jmcphers previously approved these changes Jun 26, 2025
Copy link
Collaborator

@jmcphers jmcphers left a comment

Choose a reason for hiding this comment

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

I did some debugging and found that the problem was that I had no pip in my uv environment. I don't know enough about uv to know if this is normal or not. It does work once I have pip installed!

Python 3.11.12 (Uv: .venv) started.
Python 3.11.12 (main, May 22 2025, 01:39:08) [Clang 20.1.4 ]
Type 'copyright', 'credits' or 'license' for more information
IPython 8.18.1 -- An enhanced Interactive Python. Type '?' for help.
Automatic import reloading for Python is enabled. It can be disabled with the [python.enableAutoReload setting](vscode-file://vscode-app/Users/jmcphers/git/positron/out/vs/code/electron-sandbox/workbench/workbench-dev.html#).
>>> pip
/Users/jmcphers/data/errata/.venv/bin/python: No module named pip
Note: you may need to restart the kernel to use updated packages.

My only other feedback is that the tool returns (and declares success) after it initiates the package install, but before the packages are actually installed. This means it won't be able to help troubleshoot installation errors and may presume that the packages are installed later in the conversation when they aren't. Still an improvement over what we have today, though!

@nstrayer
Copy link
Contributor Author

Updated so that the tool knows the result of the install command.
image

@nstrayer nstrayer changed the base branch from main to prerelease/2025.07 June 27, 2025 00:48
@nstrayer nstrayer force-pushed the smarter-assistant-python-pkg-install branch from 6ef09ef to 631dc9a Compare June 27, 2025 00:53
nstrayer added 10 commits June 26, 2025 20:55
Creates InstallPackagesCommandHandler with validation, error handling, and support for multiple package managers through the existing installation channel system.
Adds command registration, constants, and service bindings to expose installPackages command through VS Code's command system.
Implements installPythonPackage tool with terminal confirmation dialogs and structured error handling for different failure scenarios.
Adds comprehensive installation workflow guidance and examples to prevent \!pip usage and ensure proper tool usage.
@nstrayer nstrayer force-pushed the smarter-assistant-python-pkg-install branch from 631dc9a to f4dcde0 Compare June 27, 2025 00:55
@nstrayer nstrayer force-pushed the smarter-assistant-python-pkg-install branch from 5422284 to d3c9124 Compare June 27, 2025 00:58
@nstrayer nstrayer merged commit ae69906 into prerelease/2025.07 Jun 27, 2025
33 of 48 checks passed
@nstrayer nstrayer deleted the smarter-assistant-python-pkg-install branch June 27, 2025 15:13
@github-actions github-actions bot locked and limited conversation to collaborators Jun 27, 2025
@nstrayer nstrayer restored the smarter-assistant-python-pkg-install branch June 27, 2025 17:50
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