-
Notifications
You must be signed in to change notification settings - Fork 215
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(vscode): add copilot chat participant (#2393)
- Loading branch information
Showing
23 changed files
with
839 additions
and
203 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -77,3 +77,5 @@ apps/vscode-e2e/.screenshots | |
.nx/powerpack | ||
**/cypress/downloads | ||
migrations.json | ||
|
||
test-output |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
{ | ||
"extends": ["../../../.eslintrc.json"], | ||
"ignorePatterns": ["!**/*"], | ||
"overrides": [ | ||
{ | ||
"files": ["*.ts", "*.tsx", "*.js", "*.jsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.ts", "*.tsx"], | ||
"rules": {} | ||
}, | ||
{ | ||
"files": ["*.js", "*.jsx"], | ||
"rules": {} | ||
} | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
{ | ||
"jsc": { | ||
"target": "es2017", | ||
"parser": { | ||
"syntax": "typescript", | ||
"decorators": true, | ||
"dynamicImport": true | ||
}, | ||
"transform": { | ||
"decoratorMetadata": true, | ||
"legacyDecorator": true | ||
}, | ||
"keepClassNames": true, | ||
"externalHelpers": true, | ||
"loose": true | ||
}, | ||
"module": { | ||
"type": "es6" | ||
}, | ||
"sourceMaps": true, | ||
"exclude": [] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
# vscode-copilot | ||
|
||
This library was generated with [Nx](https://nx.dev). | ||
|
||
## Running unit tests | ||
|
||
Run `nx test vscode-copilot` to execute the unit tests via [Jest](https://jestjs.io). |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* eslint-disable */ | ||
import { readFileSync } from 'fs'; | ||
|
||
// Reading the SWC compilation config for the spec files | ||
const swcJestConfig = JSON.parse( | ||
readFileSync(`${__dirname}/.spec.swcrc`, 'utf-8') | ||
); | ||
|
||
// Disable .swcrc look-up by SWC core because we're passing in swcJestConfig ourselves | ||
swcJestConfig.swcrc = false; | ||
|
||
export default { | ||
displayName: 'vscode-copilot', | ||
preset: '../../../jest.preset.js', | ||
testEnvironment: 'node', | ||
transform: { | ||
'^.+\\.[tj]s$': ['@swc/jest', swcJestConfig], | ||
}, | ||
moduleFileExtensions: ['ts', 'js', 'html'], | ||
coverageDirectory: 'test-output/jest/coverage', | ||
passWithNoTests: true, | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "@nx-console/vscode-copilot", | ||
"version": "0.0.1", | ||
"private": true, | ||
"main": "./src/index.ts", | ||
"types": "./src/index.ts", | ||
"nx": { | ||
"name": "vscode-copilot", | ||
"sourceRoot": "libs/vscode/copilot/src", | ||
"projectType": "library", | ||
"tags": [ | ||
"type:vscode" | ||
] | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export * from './lib/init-copilot.js'; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import { | ||
CancellationToken, | ||
ChatContext, | ||
ChatRequest, | ||
ChatRequestHandler, | ||
ChatResponseStream, | ||
ExtensionContext, | ||
LanguageModelChatMessage, | ||
Uri, | ||
chat, | ||
commands, | ||
Command, | ||
} from 'vscode'; | ||
import { getNxWorkspace } from '@nx-console/vscode-nx-workspace'; | ||
import { BASE_PROMPT, GENERATE_PROMPT } from './prompt.js'; | ||
import type { TargetConfiguration } from 'nx/src/devkit-exports.js'; | ||
import { GlobalConfigurationStore } from '@nx-console/vscode-configuration'; | ||
|
||
const OPEN_COPILOT_SETTING_COMMAND = 'nxConsole.openCopilotSettings'; | ||
|
||
export function initCopilot(context: ExtensionContext) { | ||
const nxParticipant = chat.createChatParticipant('nx-console.nx', handler); | ||
nxParticipant.iconPath = Uri.joinPath( | ||
context.extensionUri, | ||
'assets', | ||
'nx.png' | ||
); | ||
} | ||
|
||
const handler: ChatRequestHandler = async ( | ||
request: ChatRequest, | ||
context: ChatContext, | ||
stream: ChatResponseStream, | ||
token: CancellationToken | ||
) => { | ||
const enableNxCopilotFeaturesSetting = GlobalConfigurationStore.instance.get( | ||
'enableNxCopilotFeatures', | ||
false | ||
); | ||
|
||
if (!enableNxCopilotFeaturesSetting) { | ||
stream.markdown( | ||
'The @nx copilot chat participant is experimental. To use it, please enable it in the settings.' | ||
); | ||
|
||
stream.button({ | ||
title: 'Enable Nx Copilot', | ||
command: 'workbench.action.openSettings', | ||
arguments: ['nxConsole.enableNxCopilotFeatures'], | ||
}); | ||
return; | ||
} | ||
const prompt = BASE_PROMPT; | ||
|
||
stream.progress('Retrieving workspace information...'); | ||
|
||
const projectGraph = await getPrunedProjectGraph(); | ||
|
||
// if (request.command === 'generate') { | ||
// prompt = GENERATE_PROMPT; | ||
// } | ||
|
||
const messages = [LanguageModelChatMessage.User(prompt)]; | ||
|
||
messages.push(LanguageModelChatMessage.User(request.prompt)); | ||
messages.push(LanguageModelChatMessage.User(JSON.stringify(projectGraph))); | ||
|
||
const chatResponse = await request.model.sendRequest(messages, {}, token); | ||
|
||
for await (const fragment of chatResponse.text) { | ||
stream.markdown(fragment); | ||
} | ||
|
||
return; | ||
}; | ||
|
||
async function getPrunedProjectGraph() { | ||
const nxWorkspace = await getNxWorkspace(); | ||
const projectGraph = nxWorkspace.projectGraph; | ||
return { | ||
nodes: Object.entries(projectGraph.nodes) | ||
.map(([name, node]) => { | ||
const prunedNode = { | ||
type: node.type, | ||
} as any; | ||
if (node.data.metadata?.technologies) { | ||
prunedNode.technologies = node.data.metadata.technologies; | ||
} | ||
if (node.data.targets) { | ||
prunedNode.targets = Object.entries(node.data.targets) | ||
.map(([key, target]) => { | ||
const prunedTarget = { | ||
executor: target.executor, | ||
} as Partial<TargetConfiguration>; | ||
if (target.command) { | ||
prunedTarget.command = target.command; | ||
} | ||
if (target.options.commands) { | ||
prunedTarget.command = target.options.commands; | ||
} | ||
if (target.configurations) { | ||
prunedTarget.configurations = Object.keys( | ||
target.configurations | ||
); | ||
} | ||
return [key, prunedTarget] as const; | ||
}) | ||
.reduce((acc, [key, target]) => { | ||
acc[key] = target; | ||
return acc; | ||
}, {}); | ||
} | ||
|
||
return [name, prunedNode] as const; | ||
}) | ||
.reduce((acc, [name, node]) => { | ||
acc[name] = node; | ||
return acc; | ||
}, {}), | ||
dependencies: Object.entries(projectGraph.dependencies) | ||
.filter(([key]) => !key.startsWith('npm:')) | ||
.map( | ||
([key, deps]) => | ||
[key, deps.filter((dep) => !dep.target.startsWith('npm:'))] as const | ||
) | ||
.reduce((acc, [key, value]) => { | ||
acc[key] = value; | ||
return acc; | ||
}, {}), | ||
}; | ||
} |
Oops, something went wrong.