Introduce command and tools for venv creation - #3554
Introduce command and tools for venv creation#3554Andrew Casey (amcasey) wants to merge 10 commits into
Conversation
Creates or updates a venv in the workspace root with "qdk[jupyter]", "ipympl", and "ipykernel". The tool behaves a bit differently from the command: - signals failures with exceptions - uses a heuristic to choose the appropriate workspace root folder - hard-codes the package list since there's no inline prompt The command version lets you tweak the list of packages to include "qdk[azure]" and/or "qdk-chemistry".
|
Jupyter discovers the venv automatically (since it's in a workspace root) but only if the notebook is in the workspace (i.e. not for an unsaved temp file). |
There was a problem hiding this comment.
Pull request overview
Adds Python virtual environment setup support to the QDK VS Code extension, exposing it both as a Command Palette command (interactive package selection) and as a GitHub Copilot tool (fixed package set) to create/update a workspace-local venv for quantum notebook development.
Changes:
- Introduces venv discovery/creation/update logic via the Python Environments extension API.
- Registers a new Command Palette command and a new Copilot tool for notebook venv setup.
- Updates extension/tool metadata and adds the
@vscode/python-environmentsdev dependency.
Reviewed changes
Copilot reviewed 6 out of 7 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| source/vscode/src/pythonEnvs.ts | New venv management helpers plus an interactive command handler. |
| source/vscode/src/gh-copilot/tools.ts | Registers a new Copilot tool that invokes the venv creation/update logic. |
| source/vscode/src/extension.ts | Registers the new Command Palette command (desktop-only). |
| source/vscode/package.json | Contributes the new command and the new language model tool metadata. |
| source/vscode/ai/qdk-programming/SKILL.md | Documents the new skill/tool entry. |
| package.json | Adds @vscode/python-environments as a dev dependency. |
| package-lock.json | Locks @vscode/python-environments@1.0.0 and its engine requirements. |
Suppressed comments (1)
source/vscode/src/gh-copilot/tools.ts:188
- The Copilot tool confirmation currently treats a missing/disabled Python Environments extension the same as "no existing venv" (because
findWorkspaceVenv()returnsfalsewhen the API isn't available). That can lead to a misleading "Create Virtual Environment" confirmation followed by a tool failure at invocation time.
confirm: async () => {
const exists = await findWorkspaceVenv();
return {
confirmationMessages: {
title: exists
|
The fix for the unrelated integration test failure is here: #3555 |
|
Can we include descriptive text in the multi-select menu? |
|
|
||
| await api.refreshEnvironments(root); | ||
| const existingEnvs = await api.getEnvironments(root); | ||
| const existingEnv = existingEnvs.find((env) => |
There was a problem hiding this comment.
I often have several Python venvs at the root of my workspace, e.g. for testing different Python versions or installed packages. Does this make the assumption there will only be one? (Seems like it will just return the first if there are multiple. It should probably ask the user to choose)
There was a problem hiding this comment.
I agree that it shouldn't silently ignore the fact that there are multiple, but the tool isn't really aimed at people who can already juggle multiple virtual environments.
Having said that, if someone already has multiple environments, it seems more likely to me that they want a fresh one for this than that they want to select an existing one to update.
There was a problem hiding this comment.
Added "active environment" as a tie breaker and more logging around just picking one.
| picked: false, | ||
| }, | ||
| { | ||
| label: "qdk[jupyter]", |
There was a problem hiding this comment.
Are these listed in the order shown? Feels like we should have the most likely/useful first (e.g. qdk[jupyter]). We may also want the qre extra in the list, being that will be a bigger focus going forward.
There was a problem hiding this comment.
Note: I think the packages you've defaulted to 'true' make sense, and the default selected packages should probably be all at the top of the list.
There was a problem hiding this comment.
They're listed in display order. My reasoning was QDK core, followed by its extras, followed by QDK Chemistry, with notebook support last.
I'm not sure I agree with putting the True ones first since that would split up the list of QDK extras. I guess we could have
- ipykernel
- ipympl
- qdk
- qdk[jupyter]
- qdk[azure]
- qdk[cirq]
- qdk[qiskit]
- qdk-chemistry
I don't love it, but it does put all the true ones at the top.
| name: "qdk-create-notebook-venv", | ||
| tool: async () => await createQuantumVenv(), | ||
| confirm: async () => { | ||
| const exists = await findWorkspaceVenv(); |
There was a problem hiding this comment.
The logic here seems a little disjointed. findWorkspaceVenv looks to see if there is a venv for the active document's workspace. But createQuantumVenv doesn't necessarily use that workspace - if there are multiple it asks the user to choose which workspace. So asking the user if they want to update or create the environment here doesn't make sense, as we don't know which workspace (or venv if they have multiple in the workspace) to ask about.
There was a problem hiding this comment.
Note that createQuantumVenv and createQuantumVenvCommand have different strategies. In the absence of the ability to prompt for a selection within the chat (and I thought showing the palette picker disrupted the flow), the tool version uses the first workspace root.
I agree that the tool experience isn't great in advanced cases and I'd be okay with removing that support entirely (though there's something to be said for the 90% case of a user with one folder and no virtual environment who just wants to ask copilot how they should proceed).
| } | ||
|
|
||
| // Quick create so the user isn't prompted | ||
| const env = await api.createEnvironment(root, { quickCreate: true }); |
There was a problem hiding this comment.
You can just pass the packages to be installed in the options too as additionalPackages, rather than the separate step below. (Though maybe cleaner or more reliable to do separately - not sure)
There was a problem hiding this comment.
Also, does this just automatically call it .venv? Looking through thier code, I'm not seeing where you can name the venv that gets created.
There was a problem hiding this comment.
I'll test additionalPackages, but the API isn't very mature and I'm pretty sure this is the way they recommended doing it.
There was a problem hiding this comment.
They call it .venv or .venv-N, according to whether there's an existing one. That's why we search first. I'm also not aware of a way to name it (and tooling support for other names isn't great).
There was a problem hiding this comment.
If you pass quickCreate: false, they show their own wizard experience, which does include a way to name the venv, but it conflicts with our package selection mechanism (they try to direct users to pypi and/or discover requirements files in the workspace).
There was a problem hiding this comment.
| placeHolder: "A virtual environment already exists at this workspace.", | ||
| }, | ||
| ); | ||
| if (choice !== "Update existing environment") return; |
There was a problem hiding this comment.
How does this code work if I have an existing venv, but I don't want to use that, I want to create a new venv with the necessary packages?
There was a problem hiding this comment.
There isn't presently a way to do that.
There was a problem hiding this comment.
I've added more logic and handling for the case where there are multiple existing environments, but I'm not really interested in building out a custom creation story (subject to change if the API support gets better) since there's already a VS Code extension (not to mention a fleet of command line tools) for doing that. This is intended to be a quick way to get the basic packages if you don't really know python and just want to focus on quantum programming / chemistry.
Creates or updates a venv in the workspace root with "qdk[jupyter]", "ipympl", and "ipykernel".
The tool behaves a bit differently from the command:
The command version lets you tweak the list of packages to include "qdk[azure]" and/or "qdk-chemistry".