From 3f4d04fb2f1bb11c2a59f5345ad55ea865064b8a Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Mon, 9 Mar 2026 13:49:27 -0700 Subject: [PATCH 1/8] remove deprecated copilot instructions flow --- source/vscode/package.json | 5 - source/vscode/src/extension.ts | 4 +- source/vscode/src/gh-copilot/instructions.ts | 342 +++---------------- 3 files changed, 53 insertions(+), 298 deletions(-) diff --git a/source/vscode/package.json b/source/vscode/package.json index da30480272..1d3f8877ed 100644 --- a/source/vscode/package.json +++ b/source/vscode/package.json @@ -522,11 +522,6 @@ "command": "qsharp-vscode.showChangelog", "title": "Show Changelog", "category": "QDK" - }, - { - "command": "qsharp-vscode.updateCopilotInstructions", - "category": "QDK", - "title": "Add Copilot instructions file for Q# and OpenQASM" } ], "breakpoints": [ diff --git a/source/vscode/src/extension.ts b/source/vscode/src/extension.ts index dc853c384e..5b8ac0fee5 100644 --- a/source/vscode/src/extension.ts +++ b/source/vscode/src/extension.ts @@ -14,7 +14,7 @@ import { CircuitEditorProvider } from "./circuitEditor.js"; import { initProjectCreator } from "./createProject.js"; import { activateDebugger } from "./debugger/activate.js"; import { startOtherQSharpDiagnostics } from "./diagnostics.js"; -import { registerGhCopilotInstructionsCommand } from "./gh-copilot/instructions.js"; +import { removeDeprecatedCopilotInstructions } from "./gh-copilot/instructions.js"; import { registerLanguageModelTools } from "./gh-copilot/tools.js"; import { activateLanguageService } from "./language-service/activate.js"; import { @@ -88,7 +88,7 @@ export async function activate( await initProjectCreator(context); registerLanguageModelTools(context); // fire-and-forget - registerGhCopilotInstructionsCommand(context); + removeDeprecatedCopilotInstructions(context); // Show prompt after update if not suppressed maybeShowChangelogPrompt(context); diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index 3c289a3a26..17037af003 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -3,254 +3,24 @@ import { log } from "qsharp-lang"; import * as vscode from "vscode"; -import { EventType, sendTelemetryEvent, UserFlowStatus } from "../telemetry"; /** - * Command to update or create the Copilot instructions file for Q# and OpenQASM. - * Shows a prompt to the user and updates the file if confirmed. + * Removes deprecated Copilot instructions from previous releases. + * We have transitioned to a tool-based approach for providing instructions to Copilot. */ -export async function updateCopilotInstructions( - trigger: "Command" | "Project" | "Activation" | "ChatToolCall", +export async function removeDeprecatedCopilotInstructions( context: vscode.ExtensionContext, ): Promise { - const globalStateUri = context.globalStorageUri; - const userInvoked = trigger === "Command" || trigger === "Project"; - - if ( - !userInvoked && - !context.globalState.get( - "showUpdateCopilotInstructionsPromptAtStartup", - true, - ) - ) { - // User has previously picked "Don't show again" - return; - } - - if (isExtensionInstructionsConfigured(globalStateUri)) { - if (trigger === "Command") { - // fire-and-forget - showInfoMessage( - "Copilot instructions for Q# and OpenQASM are already configured.", - { - showSettingButton: true, - learnMoreButton: true, - }, - ); - } - // Already configured, do nothing - return; - } - - sendTelemetryEvent( - EventType.UpdateCopilotInstructionsStart, - { - trigger, - }, - {}, - ); - - const response = await showConfirmationPrompt(userInvoked); - - if (response !== "Yes") { - sendTelemetryEvent(EventType.UpdateCopilotInstructionsEnd, { - reason: "user declined", - flowStatus: UserFlowStatus.Aborted, - }); - - if (response === "Don't show again") { - context.globalState.update( - "showUpdateCopilotInstructionsPromptAtStartup", - false, - ); - } - - // fire-and-forget - showInfoMessage( - "To add Copilot instructions for Q# and OpenQASM at any time, " + - 'run the command "QDK: Add Copilot instructions file for Q# and OpenQASM".', - { showSettingButton: false }, - ); - - // User dismissed the dialog - return; + const removedOldInstructions = await removeOldQSharpCopilotInstructions(); + if (removedOldInstructions) { + log.info("Removed old Q# instructions from copilot-instructions.md."); } - try { - // Actually add the instructions to the user's config - await addExtensionInstructionsToUserConfig(globalStateUri); - - // If we had previously updated `copilot-instructions.md` with Q# instructions, - // remove them now. Those are now obsolete. - const removedOldInstructions = await removeOldQSharpCopilotInstructions(); - - // fire-and-forget - showInfoMessage( - "Successfully configured Copilot instructions for Q# and OpenQASM" + - (removedOldInstructions - ? ", and removed old Q# instructions from copilot-instructions.md." - : "."), - { - showSettingButton: true, - learnMoreButton: true, - }, - ); - - sendTelemetryEvent( - EventType.UpdateCopilotInstructionsEnd, - { flowStatus: UserFlowStatus.Succeeded }, - {}, - ); - } catch (error) { - log.error(`Error updating Copilot instructions`, error); - vscode.window.showErrorMessage( - `Could not update Copilot instructions for Q# and OpenQASM.`, - ); - - sendTelemetryEvent( - EventType.UpdateCopilotInstructionsEnd, - { flowStatus: UserFlowStatus.Failed, reason: "Error" }, - {}, - ); - } + await removeOldCopilotInstructionsConfig(context); + await removeOldInstructionsFilesFromGlobalStorage(context); } /** - * Checks the user's instructionsFilesLocations setting to see if - * our extension's instructions directory is already included. - */ -function isExtensionInstructionsConfigured( - globalStateUri: vscode.Uri, -): boolean { - const extensionInstructionsDir = getExtensionInstructionsDir(globalStateUri); - const instructionsLocations = getConfiguredInstructionsFilesLocations(); - - // Check if our directory is in the map as a key and it's enabled (true) - if (instructionsLocations[extensionInstructionsDir] === true) { - return true; - } - return false; -} - -/** - * Updates the user's instructionsFilesLocations setting to include - * our extension's instructions directory. - */ -async function addExtensionInstructionsToUserConfig( - globalStateUri: vscode.Uri, -): Promise { - const instructionsLocations = getConfiguredInstructionsFilesLocations(); - const extensionInstructionsDir = getExtensionInstructionsDir(globalStateUri); - - // Only add the extension's chat-instructions directory - // if it's not already configured or if it's disabled - if (instructionsLocations[extensionInstructionsDir] !== true) { - // Create a new map with our directory set to true - const updatedLocations = { ...instructionsLocations }; - updatedLocations[extensionInstructionsDir] = true; - - const config = vscode.workspace.getConfiguration("chat"); - await config.update( - "instructionsFilesLocations", - updatedLocations, - vscode.ConfigurationTarget.Global, - ); - } -} - -/** - * @returns the user's `chat.instructionsFilesLocations` setting. - */ -function getConfiguredInstructionsFilesLocations(): Record { - const config = vscode.workspace.getConfiguration("chat"); - const setting = config.get>( - "instructionsFilesLocations", - {}, - ); - return setting; -} - -/** - * Gets our extension's chat instructions directory's absolute path. - * Will only work in *real* fileSystems - it's TBD how this setting - * will work if/when VS Code supports GitHub Copilot in the browser. - */ -function getExtensionInstructionsDir(globalStateUri: vscode.Uri): string { - const instructionsUri = vscode.Uri.joinPath( - globalStateUri, - "chat-instructions", - ); - - // Normalize path by removing trailing slashes and replacing backslashes with forward slashes - return instructionsUri.fsPath.replace(/[/\\]$/, "").replace(/\\/g, "/"); -} - -async function showConfirmationPrompt(userInvoked: boolean) { - const buttons = [{ title: "Yes" }, { title: "No", isCloseAffordance: true }]; - - let message = - "Add Copilot instructions for Q# and OpenQASM?\n\n" + - "This will configure GitHub Copilot to work better with Q#, OpenQASM, and other Quantum Development Kit features."; - - let response: vscode.MessageItem | undefined; - - if (!userInvoked) { - buttons.push({ title: "Don't show again" }); - // For non-modal dialogs, include a markdown link in the message - message += - "\n\nLearn more at [https://aka.ms/qdk.copilot](https://aka.ms/qdk.copilot)"; - response = await vscode.window.showInformationMessage(message, ...buttons); - } else { - // For modal dialogs, add a Learn More button - const allButtons = [...buttons, { title: "Learn More" }]; - - response = await vscode.window.showInformationMessage( - message, - { modal: true }, - ...allButtons, - ); - - // Handle the "Learn More" button click - if (response?.title === "Learn More") { - vscode.env.openExternal(vscode.Uri.parse("https://aka.ms/qdk.copilot")); - // Show the dialog again since clicking Learn More shouldn't dismiss it - return await showConfirmationPrompt(userInvoked); - } - } - - return response?.title; -} - -async function showInfoMessage( - message: string, - options: { - showSettingButton?: boolean; - learnMoreButton?: boolean; - }, -) { - const buttons: string[] = []; - if (options.showSettingButton) { - buttons.push("Show Setting"); - } - if (options.learnMoreButton) { - buttons.push("Learn More"); - } - const selection = await vscode.window.showInformationMessage( - message, - ...buttons, - ); - if (selection === "Show Setting") { - // Open the settings UI at our specific setting - vscode.commands.executeCommand( - "workbench.action.openSettings", - "chat.instructionsFilesLocations", - ); - } else if (selection === "Learn More") { - // Open the documentation URL - vscode.env.openExternal(vscode.Uri.parse("https://aka.ms/qdk.copilot")); - } -} - /** * Removes old Q# instructions from the copilot-instructions.md file if they exist. * These were only added by the QDK extension in the April 2025 release. @@ -270,8 +40,10 @@ async function removeOldQSharpCopilotInstructions(): Promise { let removed = false; for (const workspaceFolder of workspaceFolders) { - const instructionsFile = getOldInstructionsFileLocation( + const instructionsFile = vscode.Uri.joinPath( workspaceFolder.uri, + ".github", + "copilot-instructions.md", ); let text = ""; @@ -307,75 +79,63 @@ async function removeOldQSharpCopilotInstructions(): Promise { removed = true; } catch { // file doesn't exist or we couldn't edit it - continue; } } return removed; } -function getOldInstructionsFileLocation( - workspaceFolder: vscode.Uri, -): vscode.Uri { - return vscode.Uri.joinPath( - workspaceFolder, - ".github", - "copilot-instructions.md", +/** + * Removes the extension's instructions directory from `chat.instructionsFilesLocations`. + */ +async function removeOldCopilotInstructionsConfig( + context: vscode.ExtensionContext, +): Promise { + const config = vscode.workspace.getConfiguration("chat"); + const locations = config.get>( + "instructionsFilesLocations", + {}, ); -} -async function copyInstructionsFileToGlobalStorage( - context: vscode.ExtensionContext, -): Promise { - const files = ["qsharp.instructions.md", "openqasm.instructions.md"]; - let success = true; - for (const file of files) { - const source = vscode.Uri.joinPath( - context.extensionUri, - "resources", - "chat-instructions", - file, - ); + const instructionsDir = vscode.Uri.joinPath( + context.globalStorageUri, + "chat-instructions", + ) + .fsPath.replace(/[/\\]$/, "") + .replace(/\\/g, "/"); - const target = vscode.Uri.joinPath( - context.globalStorageUri, - "chat-instructions", - file, + if (locations[instructionsDir]) { + delete locations[instructionsDir]; + await config.update( + "instructionsFilesLocations", + locations, + vscode.ConfigurationTarget.Global, ); - - try { - await vscode.workspace.fs.copy(source, target, { overwrite: true }); - } catch { - success = false; - log.warn( - `Error copying Copilot instructions file from ${source.toString()} to ${target.toString()}`, - ); - } } - return success; } /** - * Registers the command to configure GitHub Copilot to use Q# and OpenQASM coding instructions. - * This updates the chat.instructionsFilesLocations setting to include the extension's - * chat-instructions directory, rather than creating a file in the user's workspace. + * Removes instructions `.md` files previously copied to global storage. */ -export async function registerGhCopilotInstructionsCommand( +async function removeOldInstructionsFilesFromGlobalStorage( context: vscode.ExtensionContext, -) { - context.subscriptions.push( - vscode.commands.registerCommand( - "qsharp-vscode.updateCopilotInstructions", - () => updateCopilotInstructions("Command", context), - ), +): Promise { + const dir = vscode.Uri.joinPath( + context.globalStorageUri, + "chat-instructions", ); - // Copy the instructions file to the global storage location - // The global storage location is stable across versions, - // but our instructions content may change from version to version. - await copyInstructionsFileToGlobalStorage(context); + for (const file of ["qsharp.instructions.md", "openqasm.instructions.md"]) { + try { + await vscode.workspace.fs.delete(vscode.Uri.joinPath(dir, file)); + } catch { + // file doesn't exist or we couldn't delete it + } + } - // Also do a one-time prompt at activation time - // fire-and-forget - updateCopilotInstructions("Activation", context); + try { + await vscode.workspace.fs.delete(dir); + } catch { + // directory doesn't exist or isn't empty + } } From 4cba687fdadc3b3d83ac8bc3e63ac5e1a168614d Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Mon, 9 Mar 2026 14:09:46 -0700 Subject: [PATCH 2/8] add telemetry to removeOldCopilotInstructions --- source/vscode/src/gh-copilot/instructions.ts | 87 ++++---------------- source/vscode/src/telemetry.ts | 16 +--- 2 files changed, 17 insertions(+), 86 deletions(-) diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index 17037af003..3f935e0be9 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -1,8 +1,8 @@ // Copyright (c) Microsoft Corporation. // Licensed under the MIT License. -import { log } from "qsharp-lang"; import * as vscode from "vscode"; +import { EventType, sendTelemetryEvent } from "../telemetry"; /** * Removes deprecated Copilot instructions from previous releases. @@ -11,78 +11,13 @@ import * as vscode from "vscode"; export async function removeDeprecatedCopilotInstructions( context: vscode.ExtensionContext, ): Promise { - const removedOldInstructions = await removeOldQSharpCopilotInstructions(); - if (removedOldInstructions) { - log.info("Removed old Q# instructions from copilot-instructions.md."); - } - - await removeOldCopilotInstructionsConfig(context); - await removeOldInstructionsFilesFromGlobalStorage(context); -} + const removedConfig = await removeOldCopilotInstructionsConfig(context); + const removedFiles = + await removeOldInstructionsFilesFromGlobalStorage(context); -/** -/** - * Removes old Q# instructions from the copilot-instructions.md file if they exist. - * These were only added by the QDK extension in the April 2025 release. - * - * @returns true if instructions were found and removed, false otherwise. - */ -async function removeOldQSharpCopilotInstructions(): Promise { - const oldCodingInstructionsTitle = - "# Q# coding instructions (updated April 2025)"; - const oldCodingInstructionsFooter = `\n\n`; - - const workspaceFolders = vscode.workspace.workspaceFolders; - if (!workspaceFolders || workspaceFolders.length === 0) { - return false; + if (removedConfig || removedFiles) { + sendTelemetryEvent(EventType.RemoveOldCopilotInstructions); } - - let removed = false; - - for (const workspaceFolder of workspaceFolders) { - const instructionsFile = vscode.Uri.joinPath( - workspaceFolder.uri, - ".github", - "copilot-instructions.md", - ); - - let text = ""; - try { - const content = await vscode.workspace.fs.readFile(instructionsFile); - text = new TextDecoder("utf-8").decode(content); - const startIndex = text.indexOf(oldCodingInstructionsTitle); - if (startIndex === -1) { - continue; - } - let endIndex = text.indexOf(oldCodingInstructionsFooter, startIndex); - - if (endIndex !== -1) { - endIndex += oldCodingInstructionsFooter.length; - // Skip any trailing newlines after the footer - while ( - endIndex < text.length && - (text[endIndex] === "\n" || text[endIndex] === "\r") - ) { - endIndex++; - } - - // Create new content without the Q# instructions - const newContent = - text.substring(0, startIndex) + text.substring(endIndex); - - // Write back the file without the Q# instructions - await vscode.workspace.fs.writeFile( - instructionsFile, - new TextEncoder().encode(newContent), - ); - } - removed = true; - } catch { - // file doesn't exist or we couldn't edit it - } - } - - return removed; } /** @@ -90,7 +25,7 @@ async function removeOldQSharpCopilotInstructions(): Promise { */ async function removeOldCopilotInstructionsConfig( context: vscode.ExtensionContext, -): Promise { +): Promise { const config = vscode.workspace.getConfiguration("chat"); const locations = config.get>( "instructionsFilesLocations", @@ -111,7 +46,9 @@ async function removeOldCopilotInstructionsConfig( locations, vscode.ConfigurationTarget.Global, ); + return true; } + return false; } /** @@ -119,7 +56,8 @@ async function removeOldCopilotInstructionsConfig( */ async function removeOldInstructionsFilesFromGlobalStorage( context: vscode.ExtensionContext, -): Promise { +): Promise { + let result = false; const dir = vscode.Uri.joinPath( context.globalStorageUri, "chat-instructions", @@ -128,6 +66,7 @@ async function removeOldInstructionsFilesFromGlobalStorage( for (const file of ["qsharp.instructions.md", "openqasm.instructions.md"]) { try { await vscode.workspace.fs.delete(vscode.Uri.joinPath(dir, file)); + result = true; } catch { // file doesn't exist or we couldn't delete it } @@ -135,7 +74,9 @@ async function removeOldInstructionsFilesFromGlobalStorage( try { await vscode.workspace.fs.delete(dir); + result = true; } catch { // directory doesn't exist or isn't empty } + return result; } diff --git a/source/vscode/src/telemetry.ts b/source/vscode/src/telemetry.ts index 36d858bf8e..4a50fb2384 100644 --- a/source/vscode/src/telemetry.ts +++ b/source/vscode/src/telemetry.ts @@ -57,8 +57,7 @@ export enum EventType { CircuitEnd = "Qsharp.CircuitEnd", LanguageModelToolStart = "Qsharp.LanguageModelToolStart", LanguageModelToolEnd = "Qsharp.LanguageModelToolEnd", - UpdateCopilotInstructionsStart = "Qsharp.UpdateCopilotInstructionsStart", - UpdateCopilotInstructionsEnd = "Qsharp.UpdateCopilotInstructionsEnd", + RemoveOldCopilotInstructions = "Qsharp.RemoveOldCopilotInstructions", ChangelogPromptStart = "Qsharp.ChangelogPromptStart", ChangelogPromptEnd = "Qsharp.ChangelogPromptEnd", } @@ -312,17 +311,8 @@ type EventTypes = { }; measurements: { timeToCompleteMs: number }; }; - [EventType.UpdateCopilotInstructionsStart]: { - properties: { - trigger: "Command" | "Project" | "Activation" | "ChatToolCall"; - }; - measurements: Empty; - }; - [EventType.UpdateCopilotInstructionsEnd]: { - properties: { - reason?: string; - flowStatus: UserFlowStatus; - }; + [EventType.RemoveOldCopilotInstructions]: { + properties: Empty; measurements: Empty; }; [EventType.ChangelogPromptStart]: { From ccca8be7d8577ea5fe33f3bf459bbf565e393d9f Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Mon, 9 Mar 2026 14:15:47 -0700 Subject: [PATCH 3/8] add qdk-read-instructions tool --- source/vscode/package.json | 20 ++++++++++++++++++++ source/vscode/src/gh-copilot/qsharpTools.ts | 14 ++++++++++++++ source/vscode/src/gh-copilot/tools.ts | 7 ++++--- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/source/vscode/package.json b/source/vscode/package.json index 1d3f8877ed..43da519062 100644 --- a/source/vscode/package.json +++ b/source/vscode/package.json @@ -1021,6 +1021,26 @@ "additionalProperties": false } }, + { + "name": "qdk-read-instructions", + "tags": [ + "azure-quantum", + "qsharp", + "qdk", + "openqasm" + ], + "toolReferenceName": "qdkReadInstructions", + "displayName": "Read Qsharp and OpenQASM Instructions Files", + "modelDescription": "Reads the contents of the instructions files for Q# and OpenQASM, which are intended to provide guidance to the language model on how to generate code in these languages. Call this tool whenever dealing with code generation or questions about code generation for Q# or OpenQASM, to ensure that the language model has the most up to date instructions on how to generate code in these languages according to best practices.", + "canBeReferencedInPrompt": true, + "icon": "./resources/file-icon-light.svg", + "inputSchema": { + "type": "object", + "properties": {}, + "required": [], + "additionalProperties": false + } + }, { "name": "qsharp-get-library-descriptions", "tags": [ diff --git a/source/vscode/src/gh-copilot/qsharpTools.ts b/source/vscode/src/gh-copilot/qsharpTools.ts index 5d9e259afc..460d16ad8b 100644 --- a/source/vscode/src/gh-copilot/qsharpTools.ts +++ b/source/vscode/src/gh-copilot/qsharpTools.ts @@ -242,6 +242,20 @@ export class QSharpTools { } } + async qdkReadInstructions(): Promise { + const readFile = async (name: string) => { + const uri = vscode.Uri.joinPath( + this.extensionUri, + "resources", + "chat-instructions", + name, + ); + const bytes = await vscode.workspace.fs.readFile(uri); + return new TextDecoder().decode(bytes); + }; + return `qsharp: ${await readFile("qsharp.instructions.md")}; openqasm: ${await readFile("openqasm.instructions.md")}`; + } + /** * Copilot tool: Returns a Markdown string summarizing all Q# standard library items, * organized by namespace. Each entry includes its signature and a short description extracted diff --git a/source/vscode/src/gh-copilot/tools.ts b/source/vscode/src/gh-copilot/tools.ts index 3a58a7ae73..2926e574e2 100644 --- a/source/vscode/src/gh-copilot/tools.ts +++ b/source/vscode/src/gh-copilot/tools.ts @@ -6,7 +6,6 @@ import * as vscode from "vscode"; import { EventType, sendTelemetryEvent, UserFlowStatus } from "../telemetry"; import { getRandomGuid } from "../utils"; import * as azqTools from "./azureQuantumTools"; -import { updateCopilotInstructions } from "./instructions"; import { QSharpTools } from "./qsharpTools"; import { CopilotToolError } from "./types"; import { ToolState } from "./azureQuantumTools"; @@ -97,6 +96,10 @@ const toolDefinitions: { name: "qdk-run-resource-estimator", tool: async (input) => await qsharpTools!.runResourceEstimator(input), }, + { + name: "qdk-read-instructions", + tool: async () => await qsharpTools!.qdkReadInstructions(), + }, { name: "qsharp-get-library-descriptions", tool: async () => await qsharpTools!.qsharpGetLibraryDescriptions(), @@ -134,8 +137,6 @@ async function invokeTool( options: vscode.LanguageModelToolInvocationOptions, toolFn: (input: T) => Promise, ): Promise { - updateCopilotInstructions("ChatToolCall", context); - const associationId = getRandomGuid(); sendTelemetryEvent(EventType.LanguageModelToolStart, { associationId, From 3b4ef47be4fd9cee934ac678c90aba934259e307 Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Mon, 9 Mar 2026 14:16:11 -0700 Subject: [PATCH 4/8] remove references to deprecated updateCopilotInstructions command --- source/vscode/package.json | 3 --- source/vscode/src/createProject.ts | 4 ---- 2 files changed, 7 deletions(-) diff --git a/source/vscode/package.json b/source/vscode/package.json index 43da519062..7737449f33 100644 --- a/source/vscode/package.json +++ b/source/vscode/package.json @@ -287,9 +287,6 @@ { "command": "qsharp-vscode.addProjectReference", "when": "resourceFilename == qsharp.json" - }, - { - "command": "qsharp-vscode.updateCopilotInstructions" } ], "view/title": [ diff --git a/source/vscode/src/createProject.ts b/source/vscode/src/createProject.ts index d01db0ff46..241628dba1 100644 --- a/source/vscode/src/createProject.ts +++ b/source/vscode/src/createProject.ts @@ -6,7 +6,6 @@ import * as vscode from "vscode"; import { qsharpExtensionId } from "./common"; import registryJson from "./registry.json"; import { EventType, sendTelemetryEvent } from "./telemetry"; -import { updateCopilotInstructions } from "./gh-copilot/instructions"; export async function initProjectCreator(context: vscode.ExtensionContext) { context.subscriptions.push( @@ -63,9 +62,6 @@ export async function initProjectCreator(context: vscode.ExtensionContext) { "Unable to create the project. Check the project files don't already exist and that the file system is writable", ); } - - // Call updateCopilotInstructions to update the Copilot instructions file - await updateCopilotInstructions("Project", context); }, ), ); From 19758cdef2314afcb42e51e123fe14abf930486a Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Mon, 9 Mar 2026 15:17:25 -0700 Subject: [PATCH 5/8] use chatInstructions instead of tools --- source/vscode/package.json | 28 ++++++-------------- source/vscode/src/gh-copilot/instructions.ts | 2 +- source/vscode/src/gh-copilot/qsharpTools.ts | 14 ---------- source/vscode/src/gh-copilot/tools.ts | 4 --- 4 files changed, 9 insertions(+), 39 deletions(-) diff --git a/source/vscode/package.json b/source/vscode/package.json index 7737449f33..dbc1337adc 100644 --- a/source/vscode/package.json +++ b/source/vscode/package.json @@ -371,6 +371,14 @@ "contents": "Connect to Azure Quantum\n[Connect to an existing workspace](command:qsharp-vscode.workspacesAdd)\nNote: For the first workspace added there may be several consent prompts to grant VS Code access.\nFor more information about the QDK and Azure Quantum, visit [https://aka.ms/AQ/Documentation](https://aka.ms/AQ/Documentation)." } ], + "chatInstructions": [ + { + "path": "./resources/chat-instructions/qsharp.instructions.md" + }, + { + "path": "./resources/chat-instructions/openqasm.instructions.md" + } + ], "commands": [ { "command": "qsharp-vscode.gotoLocations", @@ -1018,26 +1026,6 @@ "additionalProperties": false } }, - { - "name": "qdk-read-instructions", - "tags": [ - "azure-quantum", - "qsharp", - "qdk", - "openqasm" - ], - "toolReferenceName": "qdkReadInstructions", - "displayName": "Read Qsharp and OpenQASM Instructions Files", - "modelDescription": "Reads the contents of the instructions files for Q# and OpenQASM, which are intended to provide guidance to the language model on how to generate code in these languages. Call this tool whenever dealing with code generation or questions about code generation for Q# or OpenQASM, to ensure that the language model has the most up to date instructions on how to generate code in these languages according to best practices.", - "canBeReferencedInPrompt": true, - "icon": "./resources/file-icon-light.svg", - "inputSchema": { - "type": "object", - "properties": {}, - "required": [], - "additionalProperties": false - } - }, { "name": "qsharp-get-library-descriptions", "tags": [ diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index 3f935e0be9..5b47ea35ee 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -6,7 +6,7 @@ import { EventType, sendTelemetryEvent } from "../telemetry"; /** * Removes deprecated Copilot instructions from previous releases. - * We have transitioned to a tool-based approach for providing instructions to Copilot. + * We have transitioned to a chatInstructions-based approach for providing instructions to Copilot. */ export async function removeDeprecatedCopilotInstructions( context: vscode.ExtensionContext, diff --git a/source/vscode/src/gh-copilot/qsharpTools.ts b/source/vscode/src/gh-copilot/qsharpTools.ts index 460d16ad8b..5d9e259afc 100644 --- a/source/vscode/src/gh-copilot/qsharpTools.ts +++ b/source/vscode/src/gh-copilot/qsharpTools.ts @@ -242,20 +242,6 @@ export class QSharpTools { } } - async qdkReadInstructions(): Promise { - const readFile = async (name: string) => { - const uri = vscode.Uri.joinPath( - this.extensionUri, - "resources", - "chat-instructions", - name, - ); - const bytes = await vscode.workspace.fs.readFile(uri); - return new TextDecoder().decode(bytes); - }; - return `qsharp: ${await readFile("qsharp.instructions.md")}; openqasm: ${await readFile("openqasm.instructions.md")}`; - } - /** * Copilot tool: Returns a Markdown string summarizing all Q# standard library items, * organized by namespace. Each entry includes its signature and a short description extracted diff --git a/source/vscode/src/gh-copilot/tools.ts b/source/vscode/src/gh-copilot/tools.ts index 2926e574e2..1196449e1c 100644 --- a/source/vscode/src/gh-copilot/tools.ts +++ b/source/vscode/src/gh-copilot/tools.ts @@ -96,10 +96,6 @@ const toolDefinitions: { name: "qdk-run-resource-estimator", tool: async (input) => await qsharpTools!.runResourceEstimator(input), }, - { - name: "qdk-read-instructions", - tool: async () => await qsharpTools!.qdkReadInstructions(), - }, { name: "qsharp-get-library-descriptions", tool: async () => await qsharpTools!.qsharpGetLibraryDescriptions(), From 0223d38c6827b00a05200485b3e0e216ebef119f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Boechat?= Date: Mon, 9 Mar 2026 15:54:00 -0700 Subject: [PATCH 6/8] add specific dates to update comments Co-authored-by: Mine Starks <16928427+minestarks@users.noreply.github.com> --- source/vscode/src/gh-copilot/instructions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index 5b47ea35ee..db283f2ed6 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -5,7 +5,7 @@ import * as vscode from "vscode"; import { EventType, sendTelemetryEvent } from "../telemetry"; /** - * Removes deprecated Copilot instructions from previous releases. + * Removes deprecated Copilot instructions that were placed by previous releases (May 2025 - Mar 2026) * We have transitioned to a chatInstructions-based approach for providing instructions to Copilot. */ export async function removeDeprecatedCopilotInstructions( From e1e871dbdf853710875b94831b78947e2d121ac7 Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Tue, 10 Mar 2026 09:49:35 -0700 Subject: [PATCH 7/8] delete the directory recursively --- source/vscode/src/gh-copilot/instructions.ts | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-) diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index db283f2ed6..bca52ffac7 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -63,20 +63,11 @@ async function removeOldInstructionsFilesFromGlobalStorage( "chat-instructions", ); - for (const file of ["qsharp.instructions.md", "openqasm.instructions.md"]) { - try { - await vscode.workspace.fs.delete(vscode.Uri.joinPath(dir, file)); - result = true; - } catch { - // file doesn't exist or we couldn't delete it - } - } - try { - await vscode.workspace.fs.delete(dir); + await vscode.workspace.fs.delete(dir, { recursive: true }); result = true; } catch { - // directory doesn't exist or isn't empty + // directory doesn't exist or we couldn't delete it } return result; } From 779b7aad72ee636c672f67206f11bcf0d4820375 Mon Sep 17 00:00:00 2001 From: joao-boechat Date: Tue, 10 Mar 2026 09:53:32 -0700 Subject: [PATCH 8/8] add warning to directory deletion failing --- source/vscode/src/gh-copilot/instructions.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/vscode/src/gh-copilot/instructions.ts b/source/vscode/src/gh-copilot/instructions.ts index bca52ffac7..002fbd2877 100644 --- a/source/vscode/src/gh-copilot/instructions.ts +++ b/source/vscode/src/gh-copilot/instructions.ts @@ -3,6 +3,7 @@ import * as vscode from "vscode"; import { EventType, sendTelemetryEvent } from "../telemetry"; +import { log } from "qsharp-lang"; /** * Removes deprecated Copilot instructions that were placed by previous releases (May 2025 - Mar 2026) @@ -68,6 +69,7 @@ async function removeOldInstructionsFilesFromGlobalStorage( result = true; } catch { // directory doesn't exist or we couldn't delete it + log.warn(`Could not delete old instructions directory at ${dir.fsPath}`); } return result; }