Skip to content

Conversation

jmcphers
Copy link
Collaborator

@jmcphers jmcphers commented Sep 2, 2025

This change enables Github Copilot as a chat provider in Positron Assistant.

image

It works by embedding Microsoft's recently open sourced Github Copilot Chat extension in Positron, as a git submodule. The extension has been modified to work in Positron using this fork (which is also where a substantial portion of these changes live):

https://github.com/posit-dev/positron-copilot-chat

When using a Copilot model, Positron delegates most operations to Copilot (so it should work largely as it does in VS Code) but also amends Copilot's existing prompts with additional system prompts and tools, so you can ask Copilot about your sessions, have it run code for you, etc.

Release Notes

New Features

Bug Fixes

  • N/A

QA Notes

There are still some rough edges in the Copilot experience, especially around tool use, which I'll file as separate issues once this is merged.. Copilot models seem more reluctant to run code than Anthropic models do (perhaps in part to the Copilot prompting). When comparing behavior, compare like models (e.g. compare Claude Sonnet 4 in Anthropic vs Claude Sonnet 4 in Copilot).

Test tags: @:assistant

sharon-wang and others added 30 commits July 21, 2025 11:23
@jmcphers jmcphers requested a review from sharon-wang September 2, 2025 21:38
Copy link
Member

@sharon-wang sharon-wang left a comment

Choose a reason for hiding this comment

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

Looking great overall!!

I tested Ask, Edit and Agent mode with GitHub Copilot and Positron Anthropic, with a few different models, but mostly sticking to "Auto" with GitHub Copilot. I tried using some of the Copilot-specific tools, like codebase and changes, and attaching positron-provided tools such as executeCode.

A few observations, possibly to address separately?

@shiny participant runs into this error with github copilot chat

An error occurred while processing the response from the language model: Request Failed: 400 {"error":{"message":"bad request","code":"invalid_request_body"}} .

Edit mode with Positron Assistant

  1. Open workspaces/python-plots/plotly-example.py from qa-example-content open and check that it included in the context
  2. Set the chat mode to Edit
  3. Send this prompt help me make the example data a bit more interesting, so that a visually pleasant heatmap can be created
  4. Assistant keeps trying to create a new document, as it doesn't have access to tool positron_editFile_internal for some reason

On main, Positron Assistant has access to the editFile tool in Edit mode.

Edit mode with GitHub Copilot Chat

  1. Open workspaces/python-plots/plotly-example.py from qa-example-content open and check that it included in the context
  2. Set the chat mode to Edit
  3. Send this prompt help me make the example data a bit more interesting, so that a visually pleasant heatmap can be created

GitHub Copilot goes into what seems like an endless edit loop. This happens at least with model "Auto" and "o3-mini", but not necessarily with "GPT-4.1" or others.

Comment on lines 2350 to 2354
message = {
role: types.LanguageModelChatMessageRole.User,
content: [new types.LanguageModelTextPart('')],
name: undefined
} as vscode.LanguageModelChatMessage;
Copy link
Member

Choose a reason for hiding this comment

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

suggestion to construct the message instead of type assertion:

Suggested change
message = {
role: types.LanguageModelChatMessageRole.User,
content: [new types.LanguageModelTextPart('')],
name: undefined
} as vscode.LanguageModelChatMessage;
message = new types.LanguageModelChatMessage(
types.LanguageModelChatMessageRole.User,
[new types.LanguageModelTextPart('')],
undefined
);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh that's nicer! done in a3c8a05

Comment on lines 467 to 493
function stringifyPromptNodeJSON(node: JSONTree.PromptNodeJSON, strs: string[]): void {
if (node.type === JSONTree.PromptNodeType.Text) {
if (node.lineBreakBefore) {
strs.push('\n');
}
if (typeof node.text === 'string') {
strs.push(node.text);
}
} else if (node.type === JSONTree.PromptNodeType.Piece) {
if (node.ctor === JSONTree.PieceCtorKind.ImageChatMessage) {
strs.push('<image>');
} else if (node.ctor === JSONTree.PieceCtorKind.BaseChatMessage || node.ctor === JSONTree.PieceCtorKind.Other) {
for (const child of node.children) {
stringifyPromptNodeJSON(child, strs);
}
}
} else if (node.type === JSONTree.PromptNodeType.Opaque) {
// For opaque nodes, try to convert the value to string
const opaqueNode = node as JSONTree.OpaqueJSON;
if (typeof opaqueNode.value === 'string') {
strs.push(opaqueNode.value);
} else if (opaqueNode.value) {
strs.push(JSON.stringify(opaqueNode.value));
}
}
}

Copy link
Member

Choose a reason for hiding this comment

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

Are there other possible node types beyond these cases? Should we add an else just in case?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, there are only 3 node types and they're all covered here... but it wouldn't hurt to add an else in case this list changes in the future? Done in 415843e

@@ -1601,16 +1605,6 @@
"is_secret": false
}
],
"src/vs/workbench/api/node/loopbackServer.ts": [
Copy link
Member

Choose a reason for hiding this comment

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

are these still getting removed when running the detect secrets tasks via the task detect-secrets - update and audit baseline?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

No, I ran detect-secrets directly as has been my habit. Apparently this is not quite the same? I ran via the task and they're back now. 54119bd

Copy link
Member

Choose a reason for hiding this comment

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

it is a bit different! The method via the script/tasks includes this flag when running detect-secrets which enables additional checks: --force-use-all-plugins

Comment on lines 4131 to 4141
"node_modules/react": {
"version": "19.1.1",
"resolved": "https://registry.npmjs.org/react/-/react-19.1.1.tgz",
"integrity": "sha512-w8nqGImo45dmMIfljjMwOGtbmC/mk4CMYhWIicdSflH91J9TyCyczcPFXJzrZ/ZXcgGRFeP6BU0BEJTw6tZdfQ==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
},
Copy link
Member

Choose a reason for hiding this comment

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

After running npm i locally, this seems to be removed for me

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

cleaned up in a3c8a05!

Comment on lines +53 to 57
// Note: The 'anthropic' provider name is taken by Copilot Chat; we
// use 'anthropic-api' instead to make it possible to differentiate
// the two.
id: 'anthropic-api',
displayName: 'Anthropic'
Copy link
Member

Choose a reason for hiding this comment

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

Maybe to address separately:

Along these lines, when the Chat: Manage Language Models... command is run, "Anthropic" shows up twice. The first one is functional and refers to our Anthropic provider

image

It seems like from Azure downwards, clicking on those options has no effect unless you're authenticated, e.g. when I am authenticated with OpenAI, clicking on it gives a option.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think we can tackle this later, it's already pretty busted even on main. :-( Filed as #9283.

@jmcphers
Copy link
Collaborator Author

jmcphers commented Sep 3, 2025

@shiny participant runs into this error with github copilot chat

I could not reproduce this. :-/ Can you share anything else about the model you used, prompt you used, and file context?

image

Edit mode with Positron Assistant

Good catch, I discovered why this was happening! Fixed in 9538cce.

Edit mode with GitHub Copilot Chat

The less powerful models seem to struggle with edits and I'm not sure it's something we can fix (at least not in this PR). :-/

@jmcphers jmcphers requested a review from sharon-wang September 3, 2025 23:17
@sharon-wang
Copy link
Member

@shiny participant runs into this error with github copilot chat

I could not reproduce this. :-/ Can you share anything else about the model you used, prompt you used, and file context?

Ah, I think the issue occurs if I switch over to another model (e.g. Auto) after starting with the supported model Claude 4 Sonnet

shiny-assistant-model-error.mp4

sharon-wang
sharon-wang previously approved these changes Sep 4, 2025
Copy link
Member

@sharon-wang sharon-wang left a comment

Choose a reason for hiding this comment

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

Edit mode with Positron Assistant -- edit file tool is in use again ✅

Looking good! Just the secrets baseline conflict, otherwise I think it's ready to ship :shipit: 🎉

@sharon-wang
Copy link
Member

One last idea, could be worth adding a task to tasks.json to make building the copilot extension easier -- maybe something like:

		{
			"label": "compile positron-copilot-chat",
			"type": "shell",
			"command": "git submodule update --init --recursive && cd extensions/positron-copilot-chat && npm run compile",
			"options": {
				"cwd": "${workspaceFolder}"
			},
			"problemMatcher": [],
		}

@jmcphers
Copy link
Collaborator Author

jmcphers commented Sep 4, 2025

could be worth adding a task to tasks.json

I like that, done in 894b7a2

@jmcphers jmcphers merged commit 0893ada into main Sep 4, 2025
9 checks passed
@jmcphers jmcphers deleted the feature/enable-github-copilot branch September 4, 2025 23:53
@github-actions github-actions bot locked and limited conversation to collaborators Sep 4, 2025
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