├── code ├── 03 │ ├── vscode-chatflow │ │ ├── question_embeddings.jinja2 │ │ ├── .vscode │ │ │ └── settings.json │ │ ├── requirements.txt │ │ ├── answer.jinja2 │ │ ├── __pycache__ │ │ │ ├── search_kb.cpython-310.pycZone.Identifier │ │ │ ├── search_kb.cpython-310.pyc │ │ │ └── search_kb.cpython-39.pyc │ │ ├── chat.jinja2 │ │ ├── flow.meta.yaml │ │ ├── .promptflow │ │ │ ├── flow.layout.json │ │ │ ├── flow.output.json │ │ │ ├── flow.tools.json │ │ │ └── flow.log │ │ ├── search_kb.py │ │ └── flow.dag.yaml │ ├── copilotext │ │ ├── .gitignore │ │ ├── media │ │ │ ├── imgs │ │ │ │ ├── icon.png │ │ │ │ └── send.png │ │ │ └── js │ │ │ │ └── web.js │ │ ├── .vscodeignore │ │ ├── .vscode │ │ │ ├── extensions.json │ │ │ └── launch.json │ │ ├── plugins │ │ │ └── CodePlugin │ │ │ │ ├── Translate │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ │ ├── Intro │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ │ ├── Regencode │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ │ │ └── Check │ │ │ │ ├── config.json │ │ │ │ └── skprompt.txt │ │ ├── jsconfig.json │ │ ├── CHANGELOG.md │ │ ├── test │ │ │ ├── suite │ │ │ │ ├── extension.test.js │ │ │ │ └── index.js │ │ │ └── runTest.js │ │ ├── .eslintrc.json │ │ ├── copilotext.csproj │ │ ├── src │ │ │ ├── semantic-kernel.js │ │ │ ├── enterprisecopilot.js │ │ │ └── extension.js │ │ ├── copilotext.sln │ │ ├── README.md │ │ ├── vsc-extension-quickstart.md │ │ └── package.json │ └── .DS_Store ├── 02 │ ├── final │ │ ├── copilotext │ │ │ ├── .gitignore │ │ │ ├── media │ │ │ │ ├── imgs │ │ │ │ │ ├── icon.png │ │ │ │ │ └── send.png │ │ │ │ └── js │ │ │ │ │ └── web.js │ │ │ ├── .vscodeignore │ │ │ ├── .vscode │ │ │ │ ├── extensions.json │ │ │ │ └── launch.json │ │ │ ├── plugins │ │ │ │ └── CodePlugin │ │ │ │ │ ├── Translate │ │ │ │ │ ├── skprompt.txt │ │ │ │ │ └── config.json │ │ │ │ │ ├── Intro │ │ │ │ │ ├── skprompt.txt │ │ │ │ │ └── config.json │ │ │ │ │ ├── Regencode │ │ │ │ │ ├── skprompt.txt │ │ │ │ │ └── config.json │ │ │ │ │ └── Check │ │ │ │ │ ├── config.json │ │ │ │ │ └── skprompt.txt │ │ │ ├── jsconfig.json │ │ │ ├── CHANGELOG.md │ │ │ ├── test │ │ │ │ ├── suite │ │ │ │ │ ├── extension.test.js │ │ │ │ │ └── index.js │ │ │ │ └── runTest.js │ │ │ ├── .eslintrc.json │ │ │ ├── copilotext.csproj │ │ │ ├── copilotext.sln │ │ │ ├── src │ │ │ │ ├── semantic-kernel.js │ │ │ │ ├── enterprisecopilot.js │ │ │ │ └── extension.js │ │ │ ├── README.md │ │ │ ├── vsc-extension-quickstart.md │ │ │ └── package.json │ │ ├── NuGet.config │ │ └── Directory.Build.props │ └── kickoff │ │ ├── copilotext │ │ ├── .gitignore │ │ ├── media │ │ │ ├── imgs │ │ │ │ ├── icon.png │ │ │ │ └── send.png │ │ │ └── js │ │ │ │ └── web.js │ │ ├── .vscodeignore │ │ ├── .vscode │ │ │ ├── extensions.json │ │ │ └── launch.json │ │ ├── plugins │ │ │ └── CodePlugin │ │ │ │ └── Translate │ │ │ │ ├── skprompt.txt │ │ │ │ └── config.json │ │ ├── jsconfig.json │ │ ├── CHANGELOG.md │ │ ├── test │ │ │ ├── suite │ │ │ │ ├── extension.test.js │ │ │ │ └── index.js │ │ │ └── runTest.js │ │ ├── .eslintrc.json │ │ ├── copilotext.csproj │ │ ├── src │ │ │ ├── semantic-kernel.js │ │ │ ├── enterprisecopilot.js │ │ │ └── extension.js │ │ ├── copilotext.sln │ │ ├── README.md │ │ ├── package.json │ │ └── vsc-extension-quickstart.md │ │ ├── NuGet.config │ │ └── Directory.Build.props └── .DS_Store ├── .gitignore ├── .DS_Store ├── imgs ├── 00 │ ├── 01.png │ └── 02.png ├── 01 │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ ├── 06.png │ ├── 07.png │ ├── 08.png │ └── 09.png ├── 02 │ ├── sk.png │ ├── code.png │ └── translate.png └── 03 │ ├── 01.png │ ├── 02.png │ ├── 03.png │ ├── 04.png │ ├── 05.png │ ├── 06.png │ └── 07.png ├── workshop ├── .DS_Store ├── 03 │ ├── README.zh-cn.md │ ├── README.zh-tw.md │ └── README.md ├── 01 │ ├── README.zh-cn.md │ ├── README.zh-tw.md │ └── README.md └── 02 │ ├── README.zh-cn.md │ ├── README.zh-tw.md │ └── README.md ├── README.zh-cn.md ├── README.zh-tw.md └── README.md /code/03/vscode-chatflow/question_embeddings.jinja2: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /code/03/copilotext/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode-test/ 3 | *.vsix 4 | -------------------------------------------------------------------------------- /code/02/final/copilotext/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode-test/ 3 | *.vsix 4 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode-test/ 3 | *.vsix 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .vscode-test/ 3 | *.vsix 4 | bin 5 | pkg 6 | obj 7 | 8 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/.DS_Store -------------------------------------------------------------------------------- /code/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/.DS_Store -------------------------------------------------------------------------------- /imgs/00/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/00/01.png -------------------------------------------------------------------------------- /imgs/00/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/00/02.png -------------------------------------------------------------------------------- /imgs/01/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/01.png -------------------------------------------------------------------------------- /imgs/01/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/02.png -------------------------------------------------------------------------------- /imgs/01/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/03.png -------------------------------------------------------------------------------- /imgs/01/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/04.png -------------------------------------------------------------------------------- /imgs/01/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/05.png -------------------------------------------------------------------------------- /imgs/01/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/06.png -------------------------------------------------------------------------------- /imgs/01/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/07.png -------------------------------------------------------------------------------- /imgs/01/08.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/08.png -------------------------------------------------------------------------------- /imgs/01/09.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/01/09.png -------------------------------------------------------------------------------- /imgs/02/sk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/02/sk.png -------------------------------------------------------------------------------- /imgs/03/01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/01.png -------------------------------------------------------------------------------- /imgs/03/02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/02.png -------------------------------------------------------------------------------- /imgs/03/03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/03.png -------------------------------------------------------------------------------- /imgs/03/04.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/04.png -------------------------------------------------------------------------------- /imgs/03/05.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/05.png -------------------------------------------------------------------------------- /imgs/03/06.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/06.png -------------------------------------------------------------------------------- /imgs/03/07.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/03/07.png -------------------------------------------------------------------------------- /code/03/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/03/.DS_Store -------------------------------------------------------------------------------- /code/03/vscode-chatflow/.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "python.terminal.activateEnvironment": true 3 | } -------------------------------------------------------------------------------- /imgs/02/code.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/02/code.png -------------------------------------------------------------------------------- /workshop/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/workshop/.DS_Store -------------------------------------------------------------------------------- /code/03/vscode-chatflow/requirements.txt: -------------------------------------------------------------------------------- 1 | azure-search-documents==11.4.0b8 2 | azure-storage-blob 3 | azure-identity -------------------------------------------------------------------------------- /imgs/02/translate.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/imgs/02/translate.png -------------------------------------------------------------------------------- /code/03/vscode-chatflow/answer.jinja2: -------------------------------------------------------------------------------- 1 | system: 2 | Summarize the contents of user in 200 words as answer to user 3 | user: 4 | {{answer}} -------------------------------------------------------------------------------- /code/03/copilotext/media/imgs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/03/copilotext/media/imgs/icon.png -------------------------------------------------------------------------------- /code/03/copilotext/media/imgs/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/03/copilotext/media/imgs/send.png -------------------------------------------------------------------------------- /code/02/final/copilotext/media/imgs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/02/final/copilotext/media/imgs/icon.png -------------------------------------------------------------------------------- /code/02/final/copilotext/media/imgs/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/02/final/copilotext/media/imgs/send.png -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/media/imgs/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/02/kickoff/copilotext/media/imgs/icon.png -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/media/imgs/send.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/02/kickoff/copilotext/media/imgs/send.png -------------------------------------------------------------------------------- /code/03/vscode-chatflow/__pycache__/search_kb.cpython-310.pycZone.Identifier: -------------------------------------------------------------------------------- 1 | [ZoneTransfer] 2 | ZoneId=3 3 | ReferrerUrl=C:\Users\kinfeylo\Downloads\pfdemo.zip 4 | -------------------------------------------------------------------------------- /code/03/vscode-chatflow/chat.jinja2: -------------------------------------------------------------------------------- 1 | system: 2 | You are a Microsoft Fabric teacher. 3 | 4 | 5 | 6 | user: 7 | {{question}} 8 | 9 | teacher: 10 | {{answer}} 11 | -------------------------------------------------------------------------------- /code/03/vscode-chatflow/__pycache__/search_kb.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/03/vscode-chatflow/__pycache__/search_kb.cpython-310.pyc -------------------------------------------------------------------------------- /code/03/vscode-chatflow/__pycache__/search_kb.cpython-39.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/kinfey/VSCodeEnterpriseCopilotWorkshop/HEAD/code/03/vscode-chatflow/__pycache__/search_kb.cpython-39.pyc -------------------------------------------------------------------------------- /code/03/copilotext/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | test/** 4 | .gitignore 5 | .yarnrc 6 | vsc-extension-quickstart.md 7 | **/jsconfig.json 8 | **/*.map 9 | **/.eslintrc.json 10 | -------------------------------------------------------------------------------- /code/02/final/copilotext/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | test/** 4 | .gitignore 5 | .yarnrc 6 | vsc-extension-quickstart.md 7 | **/jsconfig.json 8 | **/*.map 9 | **/.eslintrc.json 10 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/.vscodeignore: -------------------------------------------------------------------------------- 1 | .vscode/** 2 | .vscode-test/** 3 | test/** 4 | .gitignore 5 | .yarnrc 6 | vsc-extension-quickstart.md 7 | **/jsconfig.json 8 | **/*.map 9 | **/.eslintrc.json 10 | -------------------------------------------------------------------------------- /code/03/copilotext/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } -------------------------------------------------------------------------------- /code/02/final/copilotext/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the extensions.json format 4 | "recommendations": [ 5 | "dbaeumer.vscode-eslint" 6 | ] 7 | } -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Translate/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a professional translator, help me translate the {{$input}} into Chinese 2 | 3 | [INPUT] 4 | Hi 5 | [END INPUT] 6 | [OUTPUT] 7 | 你好 8 | [END OUTPUT] 9 | [INPUT] 10 | {{$input}} 11 | [END INPUT] -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Translate/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a professional translator, help me translate the {{$input}} into Chinese 2 | 3 | [INPUT] 4 | Hi 5 | [END INPUT] 6 | [OUTPUT] 7 | 你好 8 | [END OUTPUT] 9 | [INPUT] 10 | {{$input}} 11 | [END INPUT] -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/plugins/CodePlugin/Translate/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a professional translator, help me translate the {{$input}} into Chinese 2 | 3 | [INPUT] 4 | Hi 5 | [END INPUT] 6 | [OUTPUT] 7 | 你好 8 | [END OUTPUT] 9 | [INPUT] 10 | {{$input}} 11 | [END INPUT] -------------------------------------------------------------------------------- /code/03/copilotext/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "checkJs": true, /* Typecheck .js files. */ 6 | "lib": [ 7 | "ES2020" 8 | ] 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /code/02/final/copilotext/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "checkJs": true, /* Typecheck .js files. */ 6 | "lib": [ 7 | "ES2020" 8 | ] 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Intro/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full stack program developer, Help me explain the code about {{$input}} as follows, 2 | 3 | 1. Tell me what programming language it is 4 | 2. Summarize the role and main functions of the code 5 | 3. Answer in English -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Regencode/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full-stack program developer, help me adjust the code in {{$input}} as follows 2 | 3 | 1. Variable names must start with ent_, 4 | 2. The function name definition must start with ENT 5 | 3. Output adjusted code only -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Intro/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full stack program developer, Help me explain the code about {{$input}} as follows, 2 | 3 | 1. Tell me what programming language it is 4 | 2. Summarize the role and main functions of the code 5 | 3. Answer in English -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Regencode/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full-stack program developer, help me adjust the code in {{$input}} as follows 2 | 3 | 1. Variable names must start with ent_, 4 | 2. The function name definition must start with ENT 5 | 3. Output adjusted code only -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "ES2020", 5 | "checkJs": true, /* Typecheck .js files. */ 6 | "lib": [ 7 | "ES2020" 8 | ] 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /code/03/copilotext/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "copilotext" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /code/02/final/copilotext/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "copilotext" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | 3 | All notable changes to the "copilotext" extension will be documented in this file. 4 | 5 | Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how to structure this file. 6 | 7 | ## [Unreleased] 8 | 9 | - Initial release -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Check/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Check Coding", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.5, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Regencode/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Regen Code", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.8, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Check/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Check Coding", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.5, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Regencode/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Regen Code", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.8, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Intro/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Introduce Coding", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.8, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Intro/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Introduce Coding", 5 | "completion": { 6 | "max_tokens": 13000, 7 | "temperature": 0.8, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Translate/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Translates English to Chinese", 5 | "completion": { 6 | "max_tokens": 1300, 7 | "temperature": 0.3, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/03/vscode-chatflow/flow.meta.yaml: -------------------------------------------------------------------------------- 1 | $schema: https://azuremlschemas.azureedge.net/latest/flow.schema.json 2 | name: template_chat_flow 3 | display_name: Template Chat Flow 4 | type: chat 5 | path: ./flow.dag.yaml 6 | description: Template Chat Flow 7 | properties: 8 | promptflow.stage: prod 9 | promptflow.section: template 10 | -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Translate/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Translates English to Chinese", 5 | "completion": { 6 | "max_tokens": 1300, 7 | "temperature": 0.3, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/plugins/CodePlugin/Translate/config.json: -------------------------------------------------------------------------------- 1 | { 2 | "schema": 1, 3 | "type": "completion", 4 | "description": "Translates English to Chinese", 5 | "completion": { 6 | "max_tokens": 1300, 7 | "temperature": 0.3, 8 | "presence_penalty": 0.0, 9 | "frequency_penalty": 0.0 10 | } 11 | } -------------------------------------------------------------------------------- /code/02/final/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /code/02/kickoff/NuGet.config: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /code/02/final/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MSBuildThisFileDirectory)..\out\pkg 8 | 9 | 10 | -------------------------------------------------------------------------------- /code/02/kickoff/Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | $(MSBuildThisFileDirectory)..\out\pkg 8 | 9 | 10 | -------------------------------------------------------------------------------- /code/03/copilotext/plugins/CodePlugin/Check/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full stack program developer, help me check whether the following code is written correctly 2 | 3 | {{$input}} 4 | 5 | Please answer according to the following conditions 6 | 7 | 1. Answer in English 8 | 2. If there is an error in the code writing, please give suggestions for modification 9 | 3. If the check is correct, please reply with a compliment, such as your code is too good -------------------------------------------------------------------------------- /code/02/final/copilotext/plugins/CodePlugin/Check/skprompt.txt: -------------------------------------------------------------------------------- 1 | You are a full stack program developer, help me check whether the following code is written correctly 2 | 3 | {{$input}} 4 | 5 | Please answer according to the following conditions 6 | 7 | 1. Answer in English 8 | 2. If there is an error in the code writing, please give suggestions for modification 9 | 3. If the check is correct, please reply with a compliment, such as your code is too good -------------------------------------------------------------------------------- /code/03/copilotext/test/suite/extension.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | const vscode = require('vscode'); 6 | // const myExtension = require('../extension'); 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.strictEqual(-1, [1, 2, 3].indexOf(5)); 13 | assert.strictEqual(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /code/02/final/copilotext/test/suite/extension.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | const vscode = require('vscode'); 6 | // const myExtension = require('../extension'); 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.strictEqual(-1, [1, 2, 3].indexOf(5)); 13 | assert.strictEqual(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/test/suite/extension.test.js: -------------------------------------------------------------------------------- 1 | const assert = require('assert'); 2 | 3 | // You can import and use all API from the 'vscode' module 4 | // as well as import your extension to test it 5 | const vscode = require('vscode'); 6 | // const myExtension = require('../extension'); 7 | 8 | suite('Extension Test Suite', () => { 9 | vscode.window.showInformationMessage('Start all tests.'); 10 | 11 | test('Sample test', () => { 12 | assert.strictEqual(-1, [1, 2, 3].indexOf(5)); 13 | assert.strictEqual(-1, [1, 2, 3].indexOf(0)); 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /code/03/copilotext/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true, 7 | "mocha": true 8 | }, 9 | "parserOptions": { 10 | "ecmaVersion": 2018, 11 | "ecmaFeatures": { 12 | "jsx": true 13 | }, 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-const-assign": "warn", 18 | "no-this-before-super": "warn", 19 | "no-undef": "warn", 20 | "no-unreachable": "warn", 21 | "no-unused-vars": "warn", 22 | "constructor-super": "warn", 23 | "valid-typeof": "warn" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code/02/final/copilotext/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true, 7 | "mocha": true 8 | }, 9 | "parserOptions": { 10 | "ecmaVersion": 2018, 11 | "ecmaFeatures": { 12 | "jsx": true 13 | }, 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-const-assign": "warn", 18 | "no-this-before-super": "warn", 19 | "no-undef": "warn", 20 | "no-unreachable": "warn", 21 | "no-unused-vars": "warn", 22 | "constructor-super": "warn", 23 | "valid-typeof": "warn" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/.eslintrc.json: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "browser": false, 4 | "commonjs": true, 5 | "es6": true, 6 | "node": true, 7 | "mocha": true 8 | }, 9 | "parserOptions": { 10 | "ecmaVersion": 2018, 11 | "ecmaFeatures": { 12 | "jsx": true 13 | }, 14 | "sourceType": "module" 15 | }, 16 | "rules": { 17 | "no-const-assign": "warn", 18 | "no-this-before-super": "warn", 19 | "no-undef": "warn", 20 | "no-unreachable": "warn", 21 | "no-unused-vars": "warn", 22 | "constructor-super": "warn", 23 | "valid-typeof": "warn" 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/copilotext.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | false 6 | $(MSBuildThisFileDirectory)/pkg 7 | bin 8 | esm 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /code/03/copilotext/copilotext.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | false 6 | $(MSBuildThisFileDirectory)/pkg 7 | bin 8 | esm 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /code/02/final/copilotext/copilotext.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net8.0 5 | false 6 | $(MSBuildThisFileDirectory)/pkg 7 | bin 8 | esm 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /code/03/vscode-chatflow/.promptflow/flow.layout.json: -------------------------------------------------------------------------------- 1 | { 2 | "nodeLayouts": { 3 | "inputs": { 4 | "x": 12, 5 | "y": 62, 6 | "index": -1 7 | }, 8 | "outputs": { 9 | "x": 12, 10 | "y": 612, 11 | "index": -1 12 | }, 13 | "question_embeddings": { 14 | "x": 175.5, 15 | "y": 148, 16 | "index": 0 17 | }, 18 | "search_kb": { 19 | "x": 176.833251953125, 20 | "y": 264, 21 | "index": 1 22 | }, 23 | "answer": { 24 | "x": 194.1666259765625, 25 | "y": 381.33331298828125, 26 | "index": 2 27 | }, 28 | "chat": { 29 | "x": 12, 30 | "y": 502, 31 | "index": 3 32 | } 33 | }, 34 | "orientation": "Vertical" 35 | } -------------------------------------------------------------------------------- /code/03/copilotext/test/runTest.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const { runTests } = require('@vscode/test-electron'); 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../'); 10 | 11 | // The path to the extension test script 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests', err); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /code/02/final/copilotext/test/runTest.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const { runTests } = require('@vscode/test-electron'); 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../'); 10 | 11 | // The path to the extension test script 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests', err); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/test/runTest.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | 3 | const { runTests } = require('@vscode/test-electron'); 4 | 5 | async function main() { 6 | try { 7 | // The folder containing the Extension Manifest package.json 8 | // Passed to `--extensionDevelopmentPath` 9 | const extensionDevelopmentPath = path.resolve(__dirname, '../'); 10 | 11 | // The path to the extension test script 12 | // Passed to --extensionTestsPath 13 | const extensionTestsPath = path.resolve(__dirname, './suite/index'); 14 | 15 | // Download VS Code, unzip it and run the integration test 16 | await runTests({ extensionDevelopmentPath, extensionTestsPath }); 17 | } catch (err) { 18 | console.error('Failed to run tests', err); 19 | process.exit(1); 20 | } 21 | } 22 | 23 | main(); 24 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/media/js/web.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // @ts-ignore 4 | window.addEventListener("message", (event) => { 5 | const message = event.data; 6 | console.log(message); 7 | switch (message.type) { 8 | case "addQA": { 9 | const divTag = document.createElement('div'); 10 | const brTag = document.createElement('br'); 11 | divTag.innerHTML = message.value; 12 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 13 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 14 | document.getElementById("taAsk").value = ""; 15 | break; 16 | } 17 | } 18 | }); 19 | 20 | 21 | })(); 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /code/03/copilotext/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ] 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceFolder}", 22 | "--extensionTestsPath=${workspaceFolder}/test/suite/index" 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /code/02/final/copilotext/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ] 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceFolder}", 22 | "--extensionTestsPath=${workspaceFolder}/test/suite/index" 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/.vscode/launch.json: -------------------------------------------------------------------------------- 1 | // A launch configuration that launches the extension inside a new window 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | { 6 | "version": "0.2.0", 7 | "configurations": [ 8 | { 9 | "name": "Run Extension", 10 | "type": "extensionHost", 11 | "request": "launch", 12 | "args": [ 13 | "--extensionDevelopmentPath=${workspaceFolder}" 14 | ] 15 | }, 16 | { 17 | "name": "Extension Tests", 18 | "type": "extensionHost", 19 | "request": "launch", 20 | "args": [ 21 | "--extensionDevelopmentPath=${workspaceFolder}", 22 | "--extensionTestsPath=${workspaceFolder}/test/suite/index" 23 | ] 24 | } 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /code/03/vscode-chatflow/.promptflow/flow.output.json: -------------------------------------------------------------------------------- 1 | { 2 | "answer": "OneLake is a key component of the Microsoft Fabric platform, providing a unified storage system for data management across enterprises. It simplifies the user experience by eliminating the need to understand infrastructure concepts or have an Azure account. With a hierarchical structure, OneLake allows users to create workspaces and lakehouses to organize and store data. It also enables easy data sharing and centralized enforcement of policy and security settings. OneLake is integrated with various Microsoft Fabric compute experiences, making it the native store for services like Data Engineering, Data Warehouse, Data Factory, Power BI, and Real-Time Analytics. Additionally, OneLake supports the use of shortcuts to access data stored in Azure Data Lake Storage and other storage systems, facilitating data composition and analysis across clouds." 3 | } -------------------------------------------------------------------------------- /code/03/vscode-chatflow/search_kb.py: -------------------------------------------------------------------------------- 1 | from typing import List 2 | from promptflow import tool 3 | from promptflow.connections import CognitiveSearchConnection 4 | 5 | from azure.core.credentials import AzureKeyCredential 6 | from azure.search.documents import SearchClient 7 | from azure.search.documents.indexes import SearchIndexClient 8 | from azure.search.documents.models import Vector 9 | 10 | 11 | @tool 12 | def search_kb(questionvector: List[float],cogconn: CognitiveSearchConnection) -> str: 13 | 14 | search_client = SearchClient(cogconn.api_base, 'promptindex', credential=AzureKeyCredential(cogconn.api_key)) 15 | vector = Vector(value=questionvector, k=3, fields="ContentVector") 16 | 17 | results = search_client.search( 18 | search_text=None, 19 | vectors=[vector], 20 | select=["KB", "Content"], 21 | ) 22 | 23 | result_item = '' 24 | 25 | for result in results: 26 | result_item = result['Content'] 27 | break 28 | 29 | return result_item 30 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/src/semantic-kernel.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('node:fs'); 3 | const path = require('node:path'); 4 | const dotnet = require('node-api-dotnet'); 5 | 6 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 7 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 8 | // const skFunc = 'CustomSKFunc'; 9 | 10 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 11 | function resolveAssembly(name) { 12 | console.log(path.join('../bin', name + '.dll')); 13 | return path.join(__dirname,'../bin', name + '.dll'); 14 | } 15 | 16 | dotnet.addListener('resolving', (name) => { 17 | const filePath = resolveAssembly(name); 18 | if (fs.existsSync(filePath)) dotnet.load(filePath); 19 | }); 20 | 21 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 22 | dotnet.load(resolveAssembly(skAssemblyName)); 23 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 24 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); -------------------------------------------------------------------------------- /code/03/copilotext/src/semantic-kernel.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('node:fs'); 3 | const path = require('node:path'); 4 | const dotnet = require('node-api-dotnet'); 5 | 6 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 7 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 8 | // const skFunc = 'CustomSKFunc'; 9 | 10 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 11 | function resolveAssembly(name) { 12 | console.log(path.join('../bin', name + '.dll')); 13 | return path.join(__dirname,'../bin', name + '.dll'); 14 | } 15 | 16 | dotnet.addListener('resolving', (name) => { 17 | const filePath = resolveAssembly(name); 18 | if (fs.existsSync(filePath)) dotnet.load(filePath); 19 | }); 20 | 21 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 22 | dotnet.load(resolveAssembly(skAssemblyName)); 23 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 24 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); 25 | 26 | // dotnet.load(resolveAssembly(skFunc)); -------------------------------------------------------------------------------- /code/03/copilotext/test/suite/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const Mocha = require('mocha'); 3 | const glob = require('glob'); 4 | 5 | function run() { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true 10 | }); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | const testFiles = new glob.Glob('**/**.test.js', { cwd: testsRoot }); 16 | const testFileStream = testFiles.stream(); 17 | 18 | testFileStream.on('data', (file) => { 19 | // Add files to the test suite 20 | mocha.addFile(path.resolve(testsRoot, file)); 21 | }); 22 | testFileStream.on('error', (err) => { 23 | e(err); 24 | }); 25 | testFileStream.on('end', () => { 26 | try { 27 | // Run the mocha test 28 | mocha.run(failures => { 29 | if (failures > 0) { 30 | e(new Error(`${failures} tests failed.`)); 31 | } else { 32 | c(); 33 | } 34 | }); 35 | } catch (err) { 36 | console.error(err); 37 | e(err); 38 | } 39 | }); 40 | }); 41 | } 42 | 43 | module.exports = { 44 | run 45 | }; 46 | -------------------------------------------------------------------------------- /code/02/final/copilotext/test/suite/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const Mocha = require('mocha'); 3 | const glob = require('glob'); 4 | 5 | function run() { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true 10 | }); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | const testFiles = new glob.Glob('**/**.test.js', { cwd: testsRoot }); 16 | const testFileStream = testFiles.stream(); 17 | 18 | testFileStream.on('data', (file) => { 19 | // Add files to the test suite 20 | mocha.addFile(path.resolve(testsRoot, file)); 21 | }); 22 | testFileStream.on('error', (err) => { 23 | e(err); 24 | }); 25 | testFileStream.on('end', () => { 26 | try { 27 | // Run the mocha test 28 | mocha.run(failures => { 29 | if (failures > 0) { 30 | e(new Error(`${failures} tests failed.`)); 31 | } else { 32 | c(); 33 | } 34 | }); 35 | } catch (err) { 36 | console.error(err); 37 | e(err); 38 | } 39 | }); 40 | }); 41 | } 42 | 43 | module.exports = { 44 | run 45 | }; 46 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/test/suite/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path'); 2 | const Mocha = require('mocha'); 3 | const glob = require('glob'); 4 | 5 | function run() { 6 | // Create the mocha test 7 | const mocha = new Mocha({ 8 | ui: 'tdd', 9 | color: true 10 | }); 11 | 12 | const testsRoot = path.resolve(__dirname, '..'); 13 | 14 | return new Promise((c, e) => { 15 | const testFiles = new glob.Glob('**/**.test.js', { cwd: testsRoot }); 16 | const testFileStream = testFiles.stream(); 17 | 18 | testFileStream.on('data', (file) => { 19 | // Add files to the test suite 20 | mocha.addFile(path.resolve(testsRoot, file)); 21 | }); 22 | testFileStream.on('error', (err) => { 23 | e(err); 24 | }); 25 | testFileStream.on('end', () => { 26 | try { 27 | // Run the mocha test 28 | mocha.run(failures => { 29 | if (failures > 0) { 30 | e(new Error(`${failures} tests failed.`)); 31 | } else { 32 | c(); 33 | } 34 | }); 35 | } catch (err) { 36 | console.error(err); 37 | e(err); 38 | } 39 | }); 40 | }); 41 | } 42 | 43 | module.exports = { 44 | run 45 | }; 46 | -------------------------------------------------------------------------------- /code/03/copilotext/media/js/web.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // @ts-ignore 4 | window.addEventListener("message", (event) => { 5 | const message = event.data; 6 | console.log(message); 7 | switch (message.type) { 8 | case "addQA": { 9 | const divTag = document.createElement('div'); 10 | const brTag = document.createElement('br'); 11 | divTag.innerHTML = message.value; 12 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 13 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 14 | document.getElementById("taAsk").value = ""; 15 | break; 16 | } 17 | case "addCode": { 18 | // @ts-ignore 19 | const divTag = document.createElement('code'); 20 | const brTag = document.createElement('br'); 21 | divTag.innerHTML = message.value; 22 | // @ts-ignore 23 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 24 | break; 25 | } 26 | } 27 | }); 28 | 29 | 30 | })(); 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /code/02/final/copilotext/media/js/web.js: -------------------------------------------------------------------------------- 1 | (function () { 2 | 3 | // @ts-ignore 4 | window.addEventListener("message", (event) => { 5 | const message = event.data; 6 | console.log(message); 7 | switch (message.type) { 8 | case "addQA": { 9 | const divTag = document.createElement('div'); 10 | const brTag = document.createElement('br'); 11 | divTag.innerHTML = message.value; 12 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 13 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 14 | document.getElementById("taAsk").value = ""; 15 | break; 16 | } 17 | case "addCode": { 18 | // @ts-ignore 19 | const divTag = document.createElement('code'); 20 | const brTag = document.createElement('br'); 21 | divTag.innerHTML = message.value; 22 | // @ts-ignore 23 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 24 | break; 25 | } 26 | } 27 | }); 28 | 29 | 30 | })(); 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /code/03/copilotext/copilotext.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "copilotext", "copilotext.csproj", "{D2A6089F-D191-4CD6-B6CD-004E35295233}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2AC99830-13C5-4A24-82E9-03B750C071D7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /code/02/final/copilotext/copilotext.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "copilotext", "copilotext.csproj", "{D2A6089F-D191-4CD6-B6CD-004E35295233}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2AC99830-13C5-4A24-82E9-03B750C071D7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/copilotext.sln: -------------------------------------------------------------------------------- 1 | 2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio Version 17 4 | VisualStudioVersion = 17.5.002.0 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "copilotext", "copilotext.csproj", "{D2A6089F-D191-4CD6-B6CD-004E35295233}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Any CPU = Debug|Any CPU 11 | Release|Any CPU = Release|Any CPU 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 15 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Debug|Any CPU.Build.0 = Debug|Any CPU 16 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.ActiveCfg = Release|Any CPU 17 | {D2A6089F-D191-4CD6-B6CD-004E35295233}.Release|Any CPU.Build.0 = Release|Any CPU 18 | EndGlobalSection 19 | GlobalSection(SolutionProperties) = preSolution 20 | HideSolutionNode = FALSE 21 | EndGlobalSection 22 | GlobalSection(ExtensibilityGlobals) = postSolution 23 | SolutionGuid = {2AC99830-13C5-4A24-82E9-03B750C071D7} 24 | EndGlobalSection 25 | EndGlobal 26 | -------------------------------------------------------------------------------- /code/03/vscode-chatflow/.promptflow/flow.tools.json: -------------------------------------------------------------------------------- 1 | { 2 | "package": {}, 3 | "code": { 4 | "question_embeddings.jinja2": { 5 | "type": "llm", 6 | "source": "question_embeddings.jinja2" 7 | }, 8 | "answer.jinja2": { 9 | "type": "llm", 10 | "inputs": { 11 | "answer": { 12 | "type": [ 13 | "string" 14 | ] 15 | } 16 | }, 17 | "source": "answer.jinja2" 18 | }, 19 | "chat.jinja2": { 20 | "type": "llm", 21 | "inputs": { 22 | "question": { 23 | "type": [ 24 | "string" 25 | ] 26 | }, 27 | "answer": { 28 | "type": [ 29 | "string" 30 | ] 31 | } 32 | }, 33 | "source": "chat.jinja2" 34 | }, 35 | "search_kb.py": { 36 | "type": "python", 37 | "inputs": { 38 | "questionvector": { 39 | "type": [ 40 | "object" 41 | ] 42 | }, 43 | "cogconn": { 44 | "type": [ 45 | "CognitiveSearchConnection" 46 | ] 47 | } 48 | }, 49 | "source": "search_kb.py", 50 | "function": "search_kb" 51 | } 52 | } 53 | } -------------------------------------------------------------------------------- /code/03/vscode-chatflow/.promptflow/flow.log: -------------------------------------------------------------------------------- 1 | 2023-09-21 14:19:19 +0800 14533 execution INFO Start to run 4 nodes with concurrency level 16. 2 | 2023-09-21 14:19:19 +0800 14533 execution.flow INFO Executing node question_embeddings. node run id: 81c1e807-6fcc-4966-899e-fbd09dfb5870_question_embeddings_0 3 | 2023-09-21 14:19:21 +0800 14533 execution.flow INFO Node question_embeddings completes. 4 | 2023-09-21 14:19:21 +0800 14533 execution.flow INFO Executing node search_kb. node run id: 81c1e807-6fcc-4966-899e-fbd09dfb5870_search_kb_0 5 | 2023-09-21 14:19:22 +0800 14533 execution.flow INFO Node search_kb completes. 6 | 2023-09-21 14:19:22 +0800 14533 execution.flow INFO Executing node answer. node run id: 81c1e807-6fcc-4966-899e-fbd09dfb5870_answer_0 7 | 2023-09-21 14:19:34 +0800 14533 execution.flow INFO Node answer completes. 8 | 2023-09-21 14:19:34 +0800 14533 execution.flow INFO Executing node chat. node run id: 81c1e807-6fcc-4966-899e-fbd09dfb5870_chat_0 9 | 2023-09-21 14:19:35 +0800 14533 execution.flow WARNING Output of chat is not json serializable, use str to store it. 10 | 2023-09-21 14:19:35 +0800 14533 execution.flow INFO Node chat completes. 11 | -------------------------------------------------------------------------------- /code/02/final/copilotext/src/semantic-kernel.js: -------------------------------------------------------------------------------- 1 | 2 | const fs = require('node:fs'); 3 | const path = require('node:path'); 4 | const dotnet = require('node-api-dotnet'); 5 | 6 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 7 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 8 | // const skFuncAssemblyName = 'Microsoft.SemanticKernel.Functions.Semantic'; 9 | 10 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 11 | function resolveAssembly(name) { 12 | console.log(path.join('../bin', name + '.dll')); 13 | return path.join(__dirname,'../bin', name + '.dll'); 14 | } 15 | 16 | dotnet.addListener('resolving', (name) => { 17 | const filePath = resolveAssembly(name); 18 | if (fs.existsSync(filePath)) dotnet.load(filePath); 19 | }); 20 | 21 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 22 | dotnet.load(resolveAssembly(skAssemblyName)); 23 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 24 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); 25 | /** @type import('../bin/Microsoft.SemanticKernel.Functions.Semantic') */ 26 | // dotnet.load(resolveAssembly(skFuncAssemblyName)); 27 | /** @type import('../bin/Microsoft.SemanticKernel.Abstractions') */ -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/src/enterprisecopilot.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const path = require('node:path'); 3 | const dotnet = require('node-api-dotnet'); 4 | require('./semantic-kernel.js'); 5 | 6 | 7 | 8 | 9 | const SK = dotnet.Microsoft.SemanticKernel; 10 | const config = vscode.workspace.getConfiguration('copilotext'); 11 | const endPoint = config.get('endpoint'); 12 | const apiKey = config.get('api_key'); 13 | const gptModel = config.get('chatgptmodel'); 14 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 15 | const pluginsDirectory = path.join(__dirname,'../plugins'); 16 | const plugins = ['CodePlugin']; 17 | 18 | 19 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 20 | 21 | 22 | async function RunInSemanticKernel(code,style) { 23 | 24 | var docFunction = code_plugin.get(style); 25 | 26 | 27 | const context_variable = new dotnet.Microsoft.SemanticKernel.Orchestration.ContextVariables(code); 28 | 29 | 30 | 31 | SK.Orchestration.FunctionResult; 32 | 33 | const answer = await SK.SKFunctionExtensions.InvokeAsync(docFunction,kernel,context_variable); 34 | 35 | 36 | return answer.toString(); 37 | 38 | } 39 | 40 | 41 | module.exports = RunInSemanticKernel; -------------------------------------------------------------------------------- /code/02/final/copilotext/src/enterprisecopilot.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const path = require('node:path'); 3 | const dotnet = require('node-api-dotnet'); 4 | require('./semantic-kernel.js'); 5 | 6 | 7 | 8 | 9 | const SK = dotnet.Microsoft.SemanticKernel; 10 | const config = vscode.workspace.getConfiguration('copilotext'); 11 | const endPoint = config.get('endpoint'); 12 | const apiKey = config.get('api_key'); 13 | const gptModel = config.get('chatgptmodel'); 14 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 15 | const pluginsDirectory = path.join(__dirname,'../plugins'); 16 | const plugins = ['CodePlugin']; 17 | 18 | 19 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 20 | 21 | async function RunInSemanticKernel(code,style) { 22 | 23 | var docFunction = code_plugin.get(style); 24 | 25 | 26 | const context_variable = new dotnet.Microsoft.SemanticKernel.Orchestration.ContextVariables(code); 27 | 28 | 29 | 30 | SK.Orchestration.FunctionResult; 31 | 32 | const answer = await SK.SKFunctionExtensions.InvokeAsync(docFunction,kernel,context_variable); 33 | 34 | 35 | return answer.toString(); 36 | 37 | } 38 | 39 | 40 | module.exports = RunInSemanticKernel; -------------------------------------------------------------------------------- /code/03/vscode-chatflow/flow.dag.yaml: -------------------------------------------------------------------------------- 1 | id: template_chat_flow 2 | name: Template Chat Flow 3 | environment: 4 | python_requirements_txt: requirements.txt 5 | inputs: 6 | question: 7 | type: string 8 | default: what is onelake 9 | outputs: 10 | answer: 11 | type: string 12 | reference: ${chat.output} 13 | is_chat_output: true 14 | nodes: 15 | - name: question_embeddings 16 | type: llm 17 | source: 18 | type: code 19 | path: question_embeddings.jinja2 20 | inputs: 21 | deployment_name: TextEmbeddingsModel 22 | input: ${inputs.question} 23 | connection: AOAIConn 24 | api: embedding 25 | - name: search_kb 26 | type: python 27 | source: 28 | type: code 29 | path: search_kb.py 30 | inputs: 31 | cogconn: AzureCogSearch 32 | questionvector: ${question_embeddings.output} 33 | aggregation: false 34 | - name: answer 35 | type: llm 36 | source: 37 | type: code 38 | path: answer.jinja2 39 | inputs: 40 | deployment_name: GPTModel 41 | temperature: 0.2 42 | answer: ${search_kb.output} 43 | max_tokens: 13000 44 | connection: AOAIConn 45 | api: chat 46 | - name: chat 47 | type: llm 48 | source: 49 | type: code 50 | path: chat.jinja2 51 | inputs: 52 | deployment_name: GPTModel 53 | temperature: 0.1 54 | question: ${inputs.question} 55 | answer: ${answer.output} 56 | connection: AOAIConn 57 | api: chat 58 | -------------------------------------------------------------------------------- /README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # **🛠️ 创建适用于企业的 Visual Studio Code Copilot 扩展** 2 | 3 | 您已成为 GitHub Copilot 的用户,利用 AI 帮助您成为专业开发人员。 但在一些企业场景下,我们会面临不同的编码需求,比如企业的编码风格、企业的测试用例编写、企业的项目文档编写要求等。您可能会发现 GitHub Copilot 需要升级,或者您可以选择 GitHub Copilot 等待名单产品,并因漫长的等待而感到沮丧。 在本次研讨会中,我将告诉您如何使用 Azure OpenAI 服务结合 Semantic Kernel 和 Promptflow 为内部企业创建定制的 Visual Studio Code Copilot 扩展。 4 | 5 | 👀 此扩展不会取代 GitHub Copilot,而是在 GitHub Copilot 的基础上添加更多企业功能。 6 | 7 | ![image](/imgs/00/01.png) 8 | 9 | 从图中我们看到通用部分是使用 GitHub Copilot 完成的,而企业部分则需要通过本次workshop中提到的方法来完成。 以下是 Workshop 的几个步骤 10 | 11 | **👣 1. Visual Studio Code 扩展开发** 12 | 13 | 您将学习如何自定义 Visual Studio Code 扩展以及如何为企业 Copilot 编程构建扩展原型 14 | 15 | 16 | ***⏲️ 时间*** 60min 17 | 18 | ***😊 学习一下*** [阅读材料](./workshop/01/README.zh-cn.md) 19 | 20 | ***👁️‍🗨️ 看看代码*** [示例代码](./code/01) 21 | 22 | **👣 2. 将 Semantic Kernel 添加到 Visual Studio Code 扩展** 23 | 24 | Semantic Kernel 是 Copilot Stack 的最佳实践。 将 Semantic Kernel 注入到 Visual Studio Code 的扩展中? 25 | 26 | ***⏲️ 时间*** 60min 27 | 28 | ***😊 学习一下*** [阅读材料](./workshop/02/README.zh-cn.md) 29 | 30 | ***👁️‍🗨️ 看看代码*** [示例代码](./code/02) 31 | 32 | 33 | **👣 3. 将 Promptflow 添加到 Visual Studio Code 扩展** 34 | 35 | 通过 Promptflow 来管理企业级代码管理 Prompt 库的新知识。 利用 Semantic Kernel 的Planner 结合 Promptflow 创建更好的人机交互体验 36 | 37 | ***⏲️ 时间*** 60min 38 | 39 | ***😊 学习一下*** [阅读材料](./workshop/03/README.zh-cn.md) 40 | 41 | ***👁️‍🗨️ 看看代码*** [示例代码](./code/03) 42 | 43 | 我们的架构是围绕 Copilot Stack 构建的 44 | 45 | ![image](/imgs/00/02.png) 46 | 47 | 48 | ## **🫵🫵 需要准备** 49 | 50 | 1. ⌛ Windows x86 / Arm 的设备 ( macOS / Linux 设备暂时不建议) 51 | 2. ⌛ 安装 NodeJS 18+ (https://nodejs.org/en/download) 52 | 3. ⌛ 安装 dotNET 8 (https://dotnet.microsoft.com/en-us/download) 53 | 4. ⌛ 安装 Python 3.10 (https://www.python.org/downloads/release/python-31012/) 54 | 5. ⌛ Azure OpenAI Service / OpenAI Service (https://azure.microsoft.com/en-us/products/ai-services/openai-service) 55 | 6. ⌛ 安装 Docker (https://www.docker.com/) -------------------------------------------------------------------------------- /README.zh-tw.md: -------------------------------------------------------------------------------- 1 | # **🛠️ 建立適用於企業的 Visual Studio Code Copilot 擴充** 2 | 3 | 您已成為 GitHub Copilot 的使用者,利用 AI 幫助您成為專業開發人員。 但在一些企業場景下,我們會面臨不同的編碼需求,比如企業的編碼風格、企業的測試使用案例編寫、企業的專案文件編寫要求等。您可能會發現 GitHub Copilot 需要升級,或者您可以選擇 GitHub Copilot 等待名單產品,並因漫長的等待而感到沮喪。 在本次研討會中,我將告訴您如何使用 Azure OpenAI 服務結合 Semantic Kernel 和 Promptflow 為內部企業建立客製的 Visual Studio Code Copilot 擴充。 4 | 5 | 👀 此擴充不會取代 GitHub Copilot,而是在 GitHub Copilot 的基礎上新增更多企業功能。 6 | 7 | ![image](/imgs/00/01.png) 8 | 9 | 從圖中我們看到通用部分是使用 GitHub Copilot 完成的,而企業部分則需要透過本次workshop中提到的方法來完成。 以下是 Workshop 的幾個步驟 10 | 11 | **👣 1. Visual Studio Code 擴充開發** 12 | 13 | 您將學習如何自訂 Visual Studio Code 擴充以及如何為企業 Copilot 程式設計建構擴充原型 14 | 15 | 16 | ***⏲️ 時間*** 60min 17 | 18 | ***😊 學習一下*** [閱讀內容](./workshop/01/README.zh-cn.md) 19 | 20 | ***👁️‍🗨️ 看看程式碼*** [範例程式碼](./code/01) 21 | 22 | **👣 2. 將 Semantic Kernel 新增到 Visual Studio Code 擴充** 23 | 24 | Semantic Kernel 是 Copilot Stack 的最佳實踐。 將 Semantic Kernel 注入到 Visual Studio Code 的擴充中? 25 | 26 | ***⏲️ 時間*** 60min 27 | 28 | ***😊 學習一下*** [閱讀內容](./workshop/02/README.zh-cn.md) 29 | 30 | ***👁️‍🗨️ 看看程式碼*** [範例程式碼](./code/02) 31 | 32 | 33 | **👣 3. 將 Promptflow 新增到 Visual Studio Code 擴充** 34 | 35 | 透過 Promptflow 來管理企業級程式碼管理 Prompt 庫的新知識。 利用 Semantic Kernel 的Planner 結合 Promptflow 建立更好的人機互動體驗 36 | 37 | ***⏲️ 時間*** 60min 38 | 39 | ***😊 學習一下*** [閱讀內容](./workshop/03/README.zh-cn.md) 40 | 41 | ***👁️‍🗨️ 看看程式碼*** [範例程式碼](./code/03) 42 | 43 | 我們的架構是圍繞 Copilot Stack 建構的 44 | 45 | ![image](/imgs/00/02.png) 46 | 47 | 48 | ## **🫵🫵 需要準備** 49 | 50 | 1. ⌛ Windows x86 / Arm 的裝置 ( macOS / Linux 裝置暫時不建議) 51 | 2. ⌛ 安裝 NodeJS 18+ (https://nodejs.org/en/download) 52 | 3. ⌛ 安裝 dotNET 8 (https://dotnet.microsoft.com/en-us/download) 53 | 4. ⌛ 安裝 Python 3.10 (https://www.python.org/downloads/release/python-31012/) 54 | 5. ⌛ Azure OpenAI Service / OpenAI Service (https://azure.microsoft.com/en-us/products/ai-services/openai-service) 55 | 6. ⌛ 安裝 Docker (https://www.docker.com/) 56 | -------------------------------------------------------------------------------- /code/03/copilotext/README.md: -------------------------------------------------------------------------------- 1 | # copilotext README 2 | 3 | This is the README for your extension "copilotext". After writing up a brief description, we recommend including the following sections. 4 | 5 | ## Features 6 | 7 | Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. 8 | 9 | For example if there is an image subfolder under your extension project workspace: 10 | 11 | \!\[feature X\]\(images/feature-x.png\) 12 | 13 | > Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. 14 | 15 | ## Requirements 16 | 17 | If you have any requirements or dependencies, add a section describing those and how to install and configure them. 18 | 19 | ## Extension Settings 20 | 21 | Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. 22 | 23 | For example: 24 | 25 | This extension contributes the following settings: 26 | 27 | * `myExtension.enable`: Enable/disable this extension. 28 | * `myExtension.thing`: Set to `blah` to do something. 29 | 30 | ## Known Issues 31 | 32 | Calling out known issues can help limit users opening duplicate issues against your extension. 33 | 34 | ## Release Notes 35 | 36 | Users appreciate release notes as you update your extension. 37 | 38 | ### 1.0.0 39 | 40 | Initial release of ... 41 | 42 | ### 1.0.1 43 | 44 | Fixed issue #. 45 | 46 | ### 1.1.0 47 | 48 | Added features X, Y, and Z. 49 | 50 | --- 51 | 52 | ## Working with Markdown 53 | 54 | You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: 55 | 56 | * Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) 57 | * Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) 58 | * Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets 59 | 60 | ## For more information 61 | 62 | * [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) 63 | * [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) 64 | 65 | **Enjoy!** 66 | -------------------------------------------------------------------------------- /code/02/final/copilotext/README.md: -------------------------------------------------------------------------------- 1 | # copilotext README 2 | 3 | This is the README for your extension "copilotext". After writing up a brief description, we recommend including the following sections. 4 | 5 | ## Features 6 | 7 | Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. 8 | 9 | For example if there is an image subfolder under your extension project workspace: 10 | 11 | \!\[feature X\]\(images/feature-x.png\) 12 | 13 | > Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. 14 | 15 | ## Requirements 16 | 17 | If you have any requirements or dependencies, add a section describing those and how to install and configure them. 18 | 19 | ## Extension Settings 20 | 21 | Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. 22 | 23 | For example: 24 | 25 | This extension contributes the following settings: 26 | 27 | * `myExtension.enable`: Enable/disable this extension. 28 | * `myExtension.thing`: Set to `blah` to do something. 29 | 30 | ## Known Issues 31 | 32 | Calling out known issues can help limit users opening duplicate issues against your extension. 33 | 34 | ## Release Notes 35 | 36 | Users appreciate release notes as you update your extension. 37 | 38 | ### 1.0.0 39 | 40 | Initial release of ... 41 | 42 | ### 1.0.1 43 | 44 | Fixed issue #. 45 | 46 | ### 1.1.0 47 | 48 | Added features X, Y, and Z. 49 | 50 | --- 51 | 52 | ## Working with Markdown 53 | 54 | You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: 55 | 56 | * Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) 57 | * Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) 58 | * Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets 59 | 60 | ## For more information 61 | 62 | * [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) 63 | * [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) 64 | 65 | **Enjoy!** 66 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/README.md: -------------------------------------------------------------------------------- 1 | # copilotext README 2 | 3 | This is the README for your extension "copilotext". After writing up a brief description, we recommend including the following sections. 4 | 5 | ## Features 6 | 7 | Describe specific features of your extension including screenshots of your extension in action. Image paths are relative to this README file. 8 | 9 | For example if there is an image subfolder under your extension project workspace: 10 | 11 | \!\[feature X\]\(images/feature-x.png\) 12 | 13 | > Tip: Many popular extensions utilize animations. This is an excellent way to show off your extension! We recommend short, focused animations that are easy to follow. 14 | 15 | ## Requirements 16 | 17 | If you have any requirements or dependencies, add a section describing those and how to install and configure them. 18 | 19 | ## Extension Settings 20 | 21 | Include if your extension adds any VS Code settings through the `contributes.configuration` extension point. 22 | 23 | For example: 24 | 25 | This extension contributes the following settings: 26 | 27 | * `myExtension.enable`: Enable/disable this extension. 28 | * `myExtension.thing`: Set to `blah` to do something. 29 | 30 | ## Known Issues 31 | 32 | Calling out known issues can help limit users opening duplicate issues against your extension. 33 | 34 | ## Release Notes 35 | 36 | Users appreciate release notes as you update your extension. 37 | 38 | ### 1.0.0 39 | 40 | Initial release of ... 41 | 42 | ### 1.0.1 43 | 44 | Fixed issue #. 45 | 46 | ### 1.1.0 47 | 48 | Added features X, Y, and Z. 49 | 50 | --- 51 | 52 | ## Working with Markdown 53 | 54 | You can author your README using Visual Studio Code. Here are some useful editor keyboard shortcuts: 55 | 56 | * Split the editor (`Cmd+\` on macOS or `Ctrl+\` on Windows and Linux) 57 | * Toggle preview (`Shift+Cmd+V` on macOS or `Shift+Ctrl+V` on Windows and Linux) 58 | * Press `Ctrl+Space` (Windows, Linux, macOS) to see a list of Markdown snippets 59 | 60 | ## For more information 61 | 62 | * [Visual Studio Code's Markdown Support](http://code.visualstudio.com/docs/languages/markdown) 63 | * [Markdown Syntax Reference](https://help.github.com/articles/markdown-basics/) 64 | 65 | **Enjoy!** 66 | -------------------------------------------------------------------------------- /code/03/copilotext/src/enterprisecopilot.js: -------------------------------------------------------------------------------- 1 | const vscode = require('vscode'); 2 | const fetch = require('node-fetch'); 3 | const path = require('node:path'); 4 | const dotnet = require('node-api-dotnet'); 5 | require('./semantic-kernel.js'); 6 | 7 | 8 | const SK = dotnet.Microsoft.SemanticKernel; 9 | const config = vscode.workspace.getConfiguration('copilotext'); 10 | const endPoint = config.get('endpoint'); 11 | const apiKey = config.get('api_key'); 12 | const gptModel = config.get('chatgptmodel'); 13 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 14 | const pluginsDirectory = path.join(__dirname,'../plugins'); 15 | const plugins = ['CodePlugin']; 16 | 17 | 18 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 19 | 20 | 21 | // const test_skill = SK.SkillDefinition.SKFunction.FromNativeFunction((name)=>demo(name)); 22 | 23 | 24 | // const test_skill = kernel.RegisterCustomFunction(SK.SkillDefinition.SKFunction.FromNativeFunction((name)=>demo(name))); 25 | 26 | 27 | // function demo(str){ 28 | // return "hello" + str; 29 | // } 30 | // const demo1 = kernel.RegisterSemanticFunction("demo", null); 31 | 32 | async function RunPlanner(qa){ 33 | 34 | const myUrl = 'http://192.168.50.231:8080/score'; 35 | const myData = {"question":qa}; 36 | 37 | const response = await fetch(myUrl, { 38 | method: 'POST', 39 | body: JSON.stringify(myData), 40 | }).then((response) => response.json()); 41 | 42 | //console.log(response); 43 | 44 | return response.answer; 45 | 46 | 47 | } 48 | 49 | 50 | 51 | async function RunInSemanticKernel(code,style) { 52 | 53 | 54 | var docFunction = code_plugin.get(style); 55 | 56 | 57 | const context_variable = new dotnet.Microsoft.SemanticKernel.Orchestration.ContextVariables(code); 58 | 59 | 60 | 61 | SK.Orchestration.FunctionResult; 62 | 63 | const answer = await SK.SKFunctionExtensions.InvokeAsync(docFunction,kernel,context_variable); 64 | 65 | 66 | return answer.ToString(); 67 | 68 | } 69 | 70 | 71 | module.exports = { 72 | RunInSemanticKernel, 73 | RunPlanner 74 | } -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copilotext", 3 | "displayName": "copilotext", 4 | "description": "", 5 | "version": "0.0.1", 6 | "engines": { 7 | "vscode": "^1.81.0" 8 | }, 9 | "categories": [ 10 | "Other" 11 | ], 12 | "activationEvents": [ 13 | ], 14 | "main": "./src/extension.js", 15 | "contributes": { 16 | "commands": [{ 17 | "command": "copilotext.addAskResponse", 18 | "title": "🤖 ask copilot" 19 | }], 20 | "viewsContainers": { 21 | "activitybar": [ 22 | { 23 | "id": "copilotext", 24 | "title": "Enterprise Copilot", 25 | "icon": "media/imgs/icon.png" 26 | } 27 | ] 28 | }, 29 | "views": { 30 | "copilotext": [ 31 | { 32 | "type": "webview", 33 | "id": "copilotext.copilotView", 34 | "name": "EnpterpriseCopilot" 35 | } 36 | ] 37 | }, 38 | "configuration": { 39 | "type": "object", 40 | "title": "copilotext", 41 | "properties": { 42 | "copilotext.endpoint": { 43 | "type": "string", 44 | "default": "Your Azure OpenAI Endpoint", 45 | "description": "Your Azure OpenAI Endpoint", 46 | "order": 0 47 | }, 48 | "copilotext.api_key": { 49 | "type": "string", 50 | "default": "Your Azure OpenAI KEY", 51 | "description": "Your Azure OpenAI KEY", 52 | "order": 1 53 | }, 54 | "copilotext.chatgptmodel": { 55 | "type": "string", 56 | "default": "Your ChatGPT Model", 57 | "description": "Your ChatGPT Model", 58 | "order": 2 59 | }, 60 | "copilotext.embeddingmodel": { 61 | "type": "string", 62 | "default": "Your Embedding Model", 63 | "description": "Your Embedding Model", 64 | "order": 3 65 | } 66 | } 67 | } 68 | }, 69 | "dependencies": { 70 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet" 71 | }, 72 | "scripts": { 73 | "lint": "eslint .", 74 | "pretest": "npm run lint", 75 | "test": "node ./test/runTest.js" 76 | }, 77 | "devDependencies": { 78 | "@types/vscode": "^1.81.0", 79 | "@types/mocha": "^10.0.1", 80 | "@types/node": "16.x", 81 | "eslint": "^8.47.0", 82 | "glob": "^10.3.3", 83 | "mocha": "^10.2.0", 84 | "typescript": "^5.1.6", 85 | "@vscode/test-electron": "^2.3.4" 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /code/03/copilotext/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `extension.js` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `extension.js` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `extension.js`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | 26 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 27 | 28 | ## Run tests 29 | 30 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 31 | * Press `F5` to run the tests in a new window with your extension loaded. 32 | * See the output of the test result in the debug console. 33 | * Make changes to `src/test/suite/extension.test.js` or create new test files inside the `test/suite` folder. 34 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 35 | * You can create folders inside the `test` folder to structure your tests any way you want. 36 | 37 | ## Go further 38 | 39 | * [Follow UX guidelines](https://code.visualstudio.com/api/ux-guidelines/overview) to create extensions that seamlessly integrate with VS Code's native interface and patterns. 40 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. 41 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 42 | -------------------------------------------------------------------------------- /code/02/final/copilotext/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `extension.js` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `extension.js` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `extension.js`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | 26 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 27 | 28 | ## Run tests 29 | 30 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 31 | * Press `F5` to run the tests in a new window with your extension loaded. 32 | * See the output of the test result in the debug console. 33 | * Make changes to `src/test/suite/extension.test.js` or create new test files inside the `test/suite` folder. 34 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 35 | * You can create folders inside the `test` folder to structure your tests any way you want. 36 | 37 | ## Go further 38 | 39 | * [Follow UX guidelines](https://code.visualstudio.com/api/ux-guidelines/overview) to create extensions that seamlessly integrate with VS Code's native interface and patterns. 40 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. 41 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 42 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/vsc-extension-quickstart.md: -------------------------------------------------------------------------------- 1 | # Welcome to your VS Code Extension 2 | 3 | ## What's in the folder 4 | 5 | * This folder contains all of the files necessary for your extension. 6 | * `package.json` - this is the manifest file in which you declare your extension and command. 7 | * The sample plugin registers a command and defines its title and command name. With this information VS Code can show the command in the command palette. It doesn’t yet need to load the plugin. 8 | * `extension.js` - this is the main file where you will provide the implementation of your command. 9 | * The file exports one function, `activate`, which is called the very first time your extension is activated (in this case by executing the command). Inside the `activate` function we call `registerCommand`. 10 | * We pass the function containing the implementation of the command as the second parameter to `registerCommand`. 11 | 12 | ## Get up and running straight away 13 | 14 | * Press `F5` to open a new window with your extension loaded. 15 | * Run your command from the command palette by pressing (`Ctrl+Shift+P` or `Cmd+Shift+P` on Mac) and typing `Hello World`. 16 | * Set breakpoints in your code inside `extension.js` to debug your extension. 17 | * Find output from your extension in the debug console. 18 | 19 | ## Make changes 20 | 21 | * You can relaunch the extension from the debug toolbar after changing code in `extension.js`. 22 | * You can also reload (`Ctrl+R` or `Cmd+R` on Mac) the VS Code window with your extension to load your changes. 23 | 24 | ## Explore the API 25 | 26 | * You can open the full set of our API when you open the file `node_modules/@types/vscode/index.d.ts`. 27 | 28 | ## Run tests 29 | 30 | * Open the debug viewlet (`Ctrl+Shift+D` or `Cmd+Shift+D` on Mac) and from the launch configuration dropdown pick `Extension Tests`. 31 | * Press `F5` to run the tests in a new window with your extension loaded. 32 | * See the output of the test result in the debug console. 33 | * Make changes to `src/test/suite/extension.test.js` or create new test files inside the `test/suite` folder. 34 | * The provided test runner will only consider files matching the name pattern `**.test.ts`. 35 | * You can create folders inside the `test` folder to structure your tests any way you want. 36 | 37 | ## Go further 38 | 39 | * [Follow UX guidelines](https://code.visualstudio.com/api/ux-guidelines/overview) to create extensions that seamlessly integrate with VS Code's native interface and patterns. 40 | * [Publish your extension](https://code.visualstudio.com/api/working-with-extensions/publishing-extension) on the VS Code extension marketplace. 41 | * Automate builds by setting up [Continuous Integration](https://code.visualstudio.com/api/working-with-extensions/continuous-integration). 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # **🛠️ Create Your Visual Studio Code Copilot Extension for Enterprise** 2 | 3 | You have become a user of GitHub Copilot, using AI to assist you in becoming a professional developer. But in some enterprise scenarios, we will face different coding requirements, such as the enterprise's coding style, the enterprise's test case writing, and the enterprise's project document writing requirements, etc. You may find that GitHub Copilot needs an upgrade, or you may choose the GitHub Copilot Waitlist product and be frustrated by the long wait. In this workshop, I will tell you how to use Azure OpenAI Service combined with Semantic Kernel and Promptflow to create a customized Visual Studio Code Copilot Extension for internal enterprises. 4 | 5 | 👀 This extension does not replace GitHub Copilot, but adds more enterprise functions based on GitHub Copilot. 6 | 7 | ![image](/imgs/00/01.png) 8 | 9 | From the diagram, we see that the general part is completed by using GitHub Copilot, while the enterprise part needs to be completed by the method mentioned in this workshop. The following are several steps of the Workshop 10 | 11 | **👣 1. Visual Studio Code Extension Development** 12 | 13 | You'll learn how to customize a Visual Studio Code extension and prototype a extension for enterprise Copilot programming 14 | 15 | ***⏲️ Hour*** 60min 16 | 17 | ***😊 Learn*** [Read](./workshop/01/README.md) 18 | 19 | ***👁️‍🗨️ Code*** [Check it](./code/01) 20 | 21 | **👣 2. Add Semantic Kernel to Visual Studio Code Extension** 22 | 23 | Semantic Kernel is the best practice of Copilot Stack. Inject Semantic Kernel into the Extension of Visual Studio Code 24 | 25 | 26 | 27 | ***⏲️ Hour*** 60min 28 | 29 | ***😊 Learn*** [Read](./workshop/02/README.md) 30 | 31 | ***👁️‍🗨️ Code*** [Check it](./code/02) 32 | 33 | **👣 3. Add Promptflow to Visual Studio Code Extension** 34 | 35 | Manage enterprise-wide code management with Promptflow New knowledge of the Prompt library. Use Semantic Kernel's Planner combined with Promptflow to create a better human-computer interaction experience 36 | 37 | Our architecture is built around the Copilot Stack 38 | 39 | 40 | ***⏲️ Hour*** 60min 41 | 42 | ***😊 Learn*** [Read](./workshop/03/README.md) 43 | 44 | ***👁️‍🗨️ Code*** [Check it](./code/03) 45 | 46 | ![image](/imgs/00/02.png) 47 | 48 | 49 | ## **🫵🫵 Need to** 50 | 51 | 1. ⌛ Windows x86 / arm Device (macOS / Linux is not recommended for the time being) 52 | 2. ⌛ NodeJS 18+ (https://nodejs.org/en/download) 53 | 3. ⌛ dotNET 8 (https://dotnet.microsoft.com/en-us/download) 54 | 4. ⌛ Python 3.10 (https://www.python.org/downloads/release/python-31012/) 55 | 5. ⌛ Azure OpenAI Service / OpenAI Service (https://azure.microsoft.com/en-us/products/ai-services/openai-service) 56 | 6. ⌛ Docker (https://www.docker.com/) 57 | 58 | 59 | 60 | ## **🤝🤝 Support** 61 | 62 | [简体中文版本点击这里](./README.zh-cn.md) 63 | 64 | [正體中文版本點擊這裡](./README.zh-tw.md) 65 | -------------------------------------------------------------------------------- /code/02/final/copilotext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copilotext", 3 | "displayName": "copilotext", 4 | "description": "", 5 | "version": "0.0.1", 6 | "engines": { 7 | "vscode": "^1.81.0" 8 | }, 9 | "categories": [ 10 | "Other" 11 | ], 12 | "activationEvents": [ 13 | ], 14 | "main": "./src/extension.js", 15 | "contributes": { 16 | "commands": [{ 17 | "command": "copilotext.checkcode", 18 | "title": "🤖 Enterprise Copilot:🔎 Check Code" 19 | }, 20 | { 21 | "command": "copilotext.introcode", 22 | "title": "🤖 Enterprise Copilot:📖 Explain Code" 23 | }, 24 | { 25 | "command": "copilotext.regencode", 26 | "title": "🤖 Enterprise Copilot:⚒️ Regeneration Code" 27 | }], 28 | "menus": { 29 | "editor/context": [ 30 | { 31 | "command": "copilotext.checkcode", 32 | "when": "editorHasSelection", 33 | "group": "copilotext-menu-group@1" 34 | }, 35 | { 36 | "command": "copilotext.introcode", 37 | "when": "editorHasSelection", 38 | "group": "copilotext-menu-group@2" 39 | }, 40 | { 41 | "command": "copilotext.regencode", 42 | "when": "editorHasSelection", 43 | "group": "copilotext-menu-group@3" 44 | } 45 | ] 46 | }, 47 | "viewsContainers": { 48 | "activitybar": [ 49 | { 50 | "id": "copilotext", 51 | "title": "Enterprise Copilot", 52 | "icon": "media/imgs/icon.png" 53 | } 54 | ] 55 | }, 56 | "views": { 57 | "copilotext": [ 58 | { 59 | "type": "webview", 60 | "id": "copilotext.copilotView", 61 | "name": "EnpterpriseCopilot" 62 | } 63 | ] 64 | }, 65 | "configuration": { 66 | "type": "object", 67 | "title": "copilotext", 68 | "properties": { 69 | "copilotext.endpoint": { 70 | "type": "string", 71 | "default": "Your Azure OpenAI Endpoint", 72 | "description": "Your Azure OpenAI Endpoint", 73 | "order": 0 74 | }, 75 | "copilotext.api_key": { 76 | "type": "string", 77 | "default": "Your Azure OpenAI KEY", 78 | "description": "Your Azure OpenAI KEY", 79 | "order": 1 80 | }, 81 | "copilotext.chatgptmodel": { 82 | "type": "string", 83 | "default": "Your ChatGPT Model", 84 | "description": "Your ChatGPT Model", 85 | "order": 2 86 | }, 87 | "copilotext.embeddingmodel": { 88 | "type": "string", 89 | "default": "Your Embedding Model", 90 | "description": "Your Embedding Model", 91 | "order": 3 92 | } 93 | } 94 | } 95 | }, 96 | "dependencies": { 97 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet" 98 | }, 99 | "scripts": { 100 | "lint": "eslint .", 101 | "pretest": "npm run lint", 102 | "test": "node ./test/runTest.js" 103 | }, 104 | "devDependencies": { 105 | "@types/vscode": "^1.81.0", 106 | "@types/mocha": "^10.0.1", 107 | "@types/node": "16.x", 108 | "eslint": "^8.47.0", 109 | "glob": "^10.3.3", 110 | "mocha": "^10.2.0", 111 | "typescript": "^5.1.6", 112 | "@vscode/test-electron": "^2.3.4" 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /code/03/copilotext/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "copilotext", 3 | "displayName": "copilotext", 4 | "description": "", 5 | "version": "0.0.1", 6 | "engines": { 7 | "vscode": "^1.81.0" 8 | }, 9 | "categories": [ 10 | "Other" 11 | ], 12 | "activationEvents": [], 13 | "main": "./src/extension.js", 14 | "contributes": { 15 | "commands": [ 16 | { 17 | "command": "copilotext.checkcode", 18 | "title": "🤖 Enterprise Copilot:🔎 Check Code" 19 | }, 20 | { 21 | "command": "copilotext.introcode", 22 | "title": "🤖 Enterprise Copilot:📖 Explain Code" 23 | }, 24 | { 25 | "command": "copilotext.regencode", 26 | "title": "🤖 Enterprise Copilot:⚒️ Regeneration Code" 27 | } 28 | ], 29 | "menus": { 30 | "editor/context": [ 31 | { 32 | "command": "copilotext.checkcode", 33 | "when": "editorHasSelection", 34 | "group": "copilotext-menu-group@1" 35 | }, 36 | { 37 | "command": "copilotext.introcode", 38 | "when": "editorHasSelection", 39 | "group": "copilotext-menu-group@2" 40 | }, 41 | { 42 | "command": "copilotext.regencode", 43 | "when": "editorHasSelection", 44 | "group": "copilotext-menu-group@3" 45 | } 46 | ] 47 | }, 48 | "viewsContainers": { 49 | "activitybar": [ 50 | { 51 | "id": "copilotext", 52 | "title": "Enterprise Copilot", 53 | "icon": "media/imgs/icon.png" 54 | } 55 | ] 56 | }, 57 | "views": { 58 | "copilotext": [ 59 | { 60 | "type": "webview", 61 | "id": "copilotext.copilotView", 62 | "name": "EnpterpriseCopilot" 63 | } 64 | ] 65 | }, 66 | "configuration": { 67 | "type": "object", 68 | "title": "copilotext", 69 | "properties": { 70 | "copilotext.endpoint": { 71 | "type": "string", 72 | "default": "Your Azure OpenAI Endpoint", 73 | "description": "Your Azure OpenAI Endpoint", 74 | "order": 0 75 | }, 76 | "copilotext.api_key": { 77 | "type": "string", 78 | "default": "Your Azure OpenAI KEY", 79 | "description": "Your Azure OpenAI KEY", 80 | "order": 1 81 | }, 82 | "copilotext.chatgptmodel": { 83 | "type": "string", 84 | "default": "Your ChatGPT Model", 85 | "description": "Your ChatGPT Model", 86 | "order": 2 87 | }, 88 | "copilotext.embeddingmodel": { 89 | "type": "string", 90 | "default": "Your Embedding Model", 91 | "description": "Your Embedding Model", 92 | "order": 3 93 | } 94 | } 95 | } 96 | }, 97 | "dependencies": { 98 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet", 99 | "node-fetch": "^2.7.0" 100 | }, 101 | "scripts": { 102 | "lint": "eslint .", 103 | "pretest": "npm run lint", 104 | "test": "node ./test/runTest.js" 105 | }, 106 | "devDependencies": { 107 | "@types/mocha": "^10.0.1", 108 | "@types/node": "16.x", 109 | "@types/vscode": "^1.81.0", 110 | "@vscode/test-electron": "^2.3.4", 111 | "eslint": "^8.47.0", 112 | "glob": "^10.3.3", 113 | "mocha": "^10.2.0", 114 | "typescript": "^5.1.6" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /workshop/03/README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # **将 Promptflow 添加到 Visual Studio Code 插件** 2 | 3 | 在 Copilot Stack 中解决问题的关键是提示。 我们在前端有 Prompt,它可以是诸如“帮我提取这段代码,分析它,并将其转换为 Python”之类的指令组合。 我们可以利用Semantic Kernel的Planner将其分为三个步骤:代码提取、分析、转换为Python。 这三个步骤中的每一个都包含一个简单的流程。 我们有大量的Flows来解决后端应用中的业务问题。 通常这些流程由固定提示组成。 如果我们尝试用微服务来拆解它,就会发现有很多相似之处。 4 | 5 | 除了Semantic Kernel框架之外,微软还发布了Promptflow。 及时解决是解决问题的关键。 您可以使用 Promptflow 来标准化相关内容。 6 | 7 | ## **PromptFlow** 8 | 9 | Prompt flow 是一套开发工具,旨在简化基于 LLM 的人工智能应用程序的端到端开发周期,从构思、原型设计、测试、评估到生产部署和监控。 它使即时工程变得更加容易,并使您能够构建具有生产质量的 LLM 应用程序。 10 | 11 | 以上文字来自PromptFlow文档(https://microsoft.github.io/promptflow/)。 以我的理解,Promptflow更适合基于后端的业务逻辑。 12 | 13 | 我们车间的企业副驾驶已经成型,但对于企业来说还远远不够。 毕竟企业可以沟通文档、生成文档、拥有自己的编码风格,这些都可以通过定制来完成。 在上一个练习中,我们在本地放置了一些Prompt处理,但是通过Promptflow我们可以使用云原生方法来完成更多操作。 14 | 15 | ## **以云原生方式构建文档聊天** 16 | 17 | Promptflow 现在不仅限于 Azure,还可以在本地和容器中使用,这意味着它更加灵活。 我们可以更加专注于发展。 18 | 19 | 安装 Promptflow 非常简单。 您可以安装 Promptflow for Visual Studio Code 的扩展并选择“安装依赖项”。 可以看到非常清晰的安装说明。 我这里就不一一描述了。 20 | 21 | 这里有一个准备工作。 您可以参考我的Microsoft Fabric博客首先使用SK将知识导入和提取到Microsoft Cognitive Search中。 (https://blog.fabric.microsoft.com/en-us/blog/use-semantic-kernel-with-lakehouse-in-microsoft-fabric) 22 | 23 | 让我们创建一个 Chatflow 。 24 | 25 | 1. 创建 ChatFlow 26 | 27 | 28 | ![image](/imgs/03/01.png) 29 | 30 | 2. 建立链接 31 | 32 | Promptflow 支持不同的链接。 此处需要配置 Azure OpenAI 连接和 Azure 认知搜索连接。 这里只需要添加链接即可。 密钥在命令行中输入。 33 | 34 | 35 | ![image](/imgs/03/02.png) 36 | 37 | 3. 了解 Promptflow 项目的结构 38 | 39 | 40 | 41 | ![image](/imgs/03/03.png) 42 | 43 | 44 | Promptflow的主要文件: 45 | 46 | a. .py - 用于与逻辑和 LLM 交互的 Python 文件 47 | 48 | b. .jinja2 - 这是提示的设置。 里面可以写Prompt,模型教育时会绑定。 49 | 50 | c. flow.dag.yaml - 这个文件非常有趣。 您可以设置执行流程的顺序,并且可以选择以可视化形式查看文件。 51 | 52 | 如果你想了解更多,可以查看https://microsoft.github.io/promptflow/how-to-guides/develop-a-flow/develop-standard-flow.html 53 | 54 | 55 | 56 | 4. 建议您直接打开示例项目 [在此下载](./code/03/vscode-chatflow) 57 | 并直接运行即可查看。 当然,您必须确保您的连接配置正确。 (不要忘记首先运行 pip install -r request.txt) 58 | 59 | 5. 在flow.dag.yaml中可以选择run、debug、deploy,完成promptflow调试。 60 | 61 | ![image](/imgs/03/04.png) 62 | 63 | 6. 本地运行就可以看到聊天界面 64 | 65 | 66 | ![image](/imgs/03/05.png) 67 | 68 | 7. 通过 http://localhost:8080/swagger.json 了解调用接口 69 | 70 | ![image](/imgs/03/06.png) 71 | 72 | 8. 添加到 Visual Studio Code 插件 73 | 74 | 安装 note-fetch 75 | 76 | ```bash 77 | 78 | npm install node-fetch@2 79 | 80 | 81 | ``` 82 | 83 | 更新 copilotenterprise.js 84 | 85 | ```js 86 | 87 | const fetch = require('node-fetch'); 88 | 89 | ......... 90 | 91 | async function RunPlanner(qa){ 92 | 93 | const myUrl = 'http://127.0.0.1:8080/score'; 94 | const myData = {"question":qa}; 95 | 96 | const response = await fetch(myUrl, { 97 | method: 'POST', 98 | body: JSON.stringify(myData), 99 | }).then((response) => response.json()); 100 | 101 | //console.log(response); 102 | 103 | return response.answer; 104 | 105 | 106 | } 107 | 108 | 109 | ``` 110 | 111 | 更改 copilotenterprise.js 112 | 113 | 114 | ```js 115 | 116 | const {RunInSemanticKernel,RunPlanner} = require('./enterprisecopilot.js'); 117 | 118 | ......... 119 | 120 | 121 | let webViewProvider={ 122 | resolveWebviewView: (_webviewView , _webviewContex) => { 123 | _webviewView.webview.options={enableScripts:true}; 124 | this.webView = _webviewView; 125 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 126 | this.webView.webview.onDidReceiveMessage( async message => { 127 | switch (message.type) { 128 | case 'addQA': 129 | 130 | const result = await RunPlanner(message.value); //await RunInSemanticKernel(message.value,"Translate"); 131 | const strQA = '🧑:
' + message.value + '
' + '🤖:
' + result + '
'; 132 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 133 | break; 134 | } 135 | }, undefined, context.subscriptions); 136 | } 137 | }; 138 | 139 | 140 | ``` 141 | 142 | 运行 143 | 144 | 145 | ![image](/imgs/03/07.png) 146 | 147 | 太棒了,您已经可以做更多的定制工作了。 当然,这个工作坊只是你的第一步,或者我们不仅仅是使用Semantic Kernel,与Promptflow结合还有更多的可能性。 148 | 149 | 150 | -------------------------------------------------------------------------------- /workshop/03/README.zh-tw.md: -------------------------------------------------------------------------------- 1 | # **將 Promptflow 新增到 Visual Studio Code 外掛** 2 | 3 | 在 Copilot Stack 中解決問題的關鍵是提示。 我們在前端有 Prompt,它可以是諸如“幫我提取這段程式碼,分析它,並將其轉換為 Python”之類別的指令組合。 我們可以利用Semantic Kernel的Planner將其分為三個步驟:程式碼提取、分析、轉換為Python。 這三個步驟中的每一個都包含一個簡單的流程。 我們有大量的Flows來解決後端應用中的業務問題。 通常這些流程由固定提示組成。 如果我們嘗試用微服務來拆解它,就會發現有很多相似之處。 4 | 5 | 除了Semantic Kernel框架之外,微軟還發布了Promptflow。 及時解決是解決問題的關鍵。 您可以使用 Promptflow 來標準化相關內容。 6 | 7 | ## **PromptFlow** 8 | 9 | Prompt flow 是一套開發工具,旨在簡化基於 LLM 的人工智慧應用程式的端到端開發週期,從構思、原型設計、測試、評估到生產部署和監控。 它使即時工程變得更加容易,並使您能夠建構具有生產品質的 LLM 應用程式。 10 | 11 | 以上文字來自PromptFlow文件(https://microsoft.github.io/promptflow/)。 以我的理解,Promptflow更適合基於後端的業務邏輯。 12 | 13 | 我們車間的企業副駕駛已經成型,但對於企業來說還遠遠不夠。 畢竟企業可以溝通文件、產生文件、擁有自己的編碼風格,這些都可以透過客製來完成。 在上一個練習中,我們在本地放置了一些Prompt處理,但是透過Promptflow我們可以使用雲原生方法來完成更多操作。 14 | 15 | ## **以雲原生方式建構文件聊天** 16 | 17 | Promptflow 現在不僅限於 Azure,還可以在本地和容器中使用,這意味著它更加靈活。 我們可以更加專注於發展。 18 | 19 | 安裝 Promptflow 非常簡單。 您可以安裝 Promptflow for Visual Studio Code 的擴充並選擇“安裝依賴項”。 可以看到非常清晰的安裝說明。 我這裡就不一一描述了。 20 | 21 | 這裡有一個準備工作。 您可以參考我的Microsoft Fabric部落格首先使用SK將知識匯入和提取到Microsoft Cognitive Search中。 (https://blog.fabric.microsoft.com/en-us/blog/use-semantic-kernel-with-lakehouse-in-microsoft-fabric) 22 | 23 | 讓我們建立一個 Chatflow 。 24 | 25 | 1. 建立 ChatFlow 26 | 27 | 28 | ![image](/imgs/03/01.png) 29 | 30 | 2. 建立連結 31 | 32 | Promptflow 支援不同的連結。 此處需要配置 Azure OpenAI 連線和 Azure 認知搜尋連線。 這裡只需要新增連結即可。 金鑰在命令列中輸入。 33 | 34 | 35 | ![image](/imgs/03/02.png) 36 | 37 | 3. 瞭解 Promptflow 專案的結構 38 | 39 | 40 | 41 | ![image](/imgs/03/03.png) 42 | 43 | 44 | Promptflow的主要檔案: 45 | 46 | a. .py - 用於與邏輯和 LLM 互動的 Python 檔案 47 | 48 | b. .jinja2 - 這是提示的設定。 裡面可以寫Prompt,模型教育時會繫結。 49 | 50 | c. flow.dag.yaml - 這個檔案非常有趣。 您可以設定執行流程的順序,並且可以選擇以視覺化形式檢視檔案。 51 | 52 | 如果你想了解更多,可以檢視https://microsoft.github.io/promptflow/how-to-guides/develop-a-flow/develop-standard-flow.html 53 | 54 | 55 | 56 | 4. 建議您直接開啟範例專案 [在此下載](./code/03/vscode-chatflow) 57 | 並直接執行即可檢視。 當然,您必須確保您的連線配置正確。 (不要忘記首先執行 pip install -r request.txt) 58 | 59 | 5. 在flow.dag.yaml中可以選擇run、debug、deploy,完成promptflow除錯。 60 | 61 | ![image](/imgs/03/04.png) 62 | 63 | 6. 本地執行就可以看到聊天介面 64 | 65 | 66 | ![image](/imgs/03/05.png) 67 | 68 | 7. 透過 http://localhost:8080/swagger.json 瞭解呼叫介面 69 | 70 | ![image](/imgs/03/06.png) 71 | 72 | 8. 新增到 Visual Studio Code 外掛 73 | 74 | 安裝 note-fetch 75 | 76 | ```bash 77 | 78 | npm install node-fetch@2 79 | 80 | 81 | ``` 82 | 83 | 更新 copilotenterprise.js 84 | 85 | ```js 86 | 87 | const fetch = require('node-fetch'); 88 | 89 | ......... 90 | 91 | async function RunPlanner(qa){ 92 | 93 | const myUrl = 'http://127.0.0.1:8080/score'; 94 | const myData = {"question":qa}; 95 | 96 | const response = await fetch(myUrl, { 97 | method: 'POST', 98 | body: JSON.stringify(myData), 99 | }).then((response) => response.json()); 100 | 101 | //console.log(response); 102 | 103 | return response.answer; 104 | 105 | 106 | } 107 | 108 | 109 | ``` 110 | 111 | 更改 copilotenterprise.js 112 | 113 | 114 | ```js 115 | 116 | const {RunInSemanticKernel,RunPlanner} = require('./enterprisecopilot.js'); 117 | 118 | ......... 119 | 120 | 121 | let webViewProvider={ 122 | resolveWebviewView: (_webviewView , _webviewContex) => { 123 | _webviewView.webview.options={enableScripts:true}; 124 | this.webView = _webviewView; 125 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 126 | this.webView.webview.onDidReceiveMessage( async message => { 127 | switch (message.type) { 128 | case 'addQA': 129 | 130 | const result = await RunPlanner(message.value); //await RunInSemanticKernel(message.value,"Translate"); 131 | const strQA = '🧑:
' + message.value + '
' + '🤖:
' + result + '
'; 132 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 133 | break; 134 | } 135 | }, undefined, context.subscriptions); 136 | } 137 | }; 138 | 139 | 140 | ``` 141 | 142 | 執行 143 | 144 | 145 | ![image](/imgs/03/07.png) 146 | 147 | 太棒了,您已經可以做更多的客製工作了。 當然,這個工作坊只是你的第一步,或者我們不僅僅是使用Semantic Kernel,與Promptflow結合還有更多的可能性。 148 | 149 | 150 | -------------------------------------------------------------------------------- /code/02/kickoff/copilotext/src/extension.js: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | const vscode = require('vscode'); 4 | // const dotnet = require('node-api-dotnet'); 5 | // const initSK = require('./enterprisecopilot.js'); 6 | const RunInSemanticKernel = require('./enterprisecopilot.js'); 7 | require('./semantic-kernel.js'); 8 | require('./enterprisecopilot.js'); 9 | 10 | // This method is called when your extension is activated 11 | // Your extension is activated the very first time the command is executed 12 | 13 | /** 14 | * @param {vscode.ExtensionContext} context 15 | */ 16 | function activate(context) { 17 | 18 | // Use the console to output diagnostic information (console.log) and errors (console.error) 19 | // This line of code will only be executed once when your extension is activated 20 | console.log('I am your AI assitanst !'); 21 | 22 | let webView; 23 | 24 | let extensionURL = context.extensionUri; 25 | 26 | 27 | let webViewProvider={ 28 | resolveWebviewView: (_webviewView , _webviewContex) => { 29 | _webviewView.webview.options={enableScripts:true}; 30 | this.webView = _webviewView; 31 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 32 | this.webView.webview.onDidReceiveMessage( async message => { 33 | switch (message.type) { 34 | case 'addQA': 35 | 36 | const result = await RunInSemanticKernel(message.value,"Translate"); 37 | const strQA = '🧑:

' + message.value + '

' + '🤖:

' + result + '

'; 38 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 39 | break; 40 | } 41 | }, undefined, context.subscriptions); 42 | } 43 | }; 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 53 | webviewOptions: { retainContextWhenHidden: true } 54 | })); 55 | 56 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 57 | 58 | 59 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 60 | }) 61 | 62 | 63 | 64 | 65 | context.subscriptions.push(ask_cmd); 66 | } 67 | 68 | 69 | function initChatViewContent(webview ,extensionURL) { 70 | 71 | 72 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 73 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 74 | 75 | return ` 76 | 77 | 78 | 79 | 80 | 81 | 🤖 Enterprise Copilot Assitant 82 | 129 | 130 | 131 |

🤖 Enterprise Copilot Assitant

132 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

133 | I can do 134 | 139 |

140 |
141 |
142 | 143 | 144 |
145 |
146 | 155 | 156 | `; 157 | 158 | } 159 | 160 | // This method is called when your extension is deactivated 161 | function deactivate() {} 162 | 163 | module.exports = { 164 | activate, 165 | deactivate 166 | } 167 | -------------------------------------------------------------------------------- /workshop/03/README.md: -------------------------------------------------------------------------------- 1 | # **Add Promptflow to Visual Studio Code Extension** 2 | 3 | The key to solving problems in Copilot Stack is Prompt. We have Prompt on the front end, which can be a combination of instructions such as "Help me extract this code, analyze it, and convert it to Python". We can use Semantic Kernel's Planner to divide it into three steps: code extraction, analysis, and conversion to Python. Each of these three steps consists of a simple Flow. We have a large number of Flows that solve business problems in back-end applications. Usually these flows are composed of fixed prompts. If we try to disassemble it using microservices, there are many similarities. 4 | 5 | In addition to the Semantic Kernel framework, Microsoft also released Promptflow. Prompt is the key to solving the problem. You can use Promptflow to standardize related content. 6 | 7 | ## **Introduce PromptFlow** 8 | 9 | Prompt flow is a suite of development tools designed to streamline the end-to-end development cycle of LLM-based AI applications, from ideation, prototyping, testing, evaluation to production deployment and monitoring. It makes prompt engineering much easier and enables you to build LLM apps with production quality. 10 | 11 | The above words are from the PromptFlow document (https://microsoft.github.io/promptflow/). In my understanding, Promptflow is more suitable for back-end-based business logic. 12 | 13 | The Enterprise Copilot in our workshop has taken shape, but it is far from enough for enterprises. After all, enterprises can communicate documents, generate documents, and have their own coding style, which can all be completed through customization. In the previous exercise, we placed some Prompt processing locally, but with Promptflow we can use cloud native methods to complete more operations. 14 | 15 | 16 | ## **Build documents in a cloud-native way Chat** 17 | 18 | Promptflow is now not just limited to Azure, but can also be used on-premises and in containers, which means it is more flexible. We can focus more on development. 19 | 20 | Installing Promptflow is very simple. You can install the Extension of Promptflow for Visual Studio Code and select Install Dependence. You can see very clear installation instructions. I won’t describe them one by one here. 21 | 22 | Here is a preparation work. You can refer to my Microsoft Fabric Blog to first use SK to import and extract knowledge into Microsoft Cognitive Search. (https://blog.fabric.microsoft.com/en-us/blog/use-semantic-kernel-with-lakehouse-in-microsoft-fabric) 23 | 24 | When you've finished logging, let's create a Chatflow . 25 | 26 | 1. Create ChatFlow 27 | 28 | 29 | ![image](/imgs/03/01.png) 30 | 31 | 2. Make Connections 32 | 33 | Promptflow supports different links. Here you need to configure Azure OpenAI Connection and Azure Cognitive Search Connection. Here you only need to add the link. The Key is entered on the command line. 34 | 35 | 36 | ![image](/imgs/03/02.png) 37 | 38 | 3. Understand the structure of Promptflow projects 39 | 40 | 41 | 42 | ![image](/imgs/03/03.png) 43 | 44 | 45 | Main files of Promptflow: 46 | 47 | a. .py - Python files for interacting with logic and LLM 48 | 49 | b. .jinja2 - This is the setting of Prompt. You can write Prompt in it, which will be bound during model education. 50 | 51 | c. flow.dag.yaml - This file is very interesting. You can set the order of execution flow, and you can choose to view the file into a visualization. 52 | 53 | If you want to know more, you can see https://microsoft.github.io/promptflow/how-to-guides/develop-a-flow/develop-standard-flow.html 54 | 55 | 56 | 57 | 4. It is recommended that you directly open the sample project [Download Here](./code/03/vscode-chatflow) 58 | and run it directly to view. Of course, you must ensure that your Connection is configured correctly. (Don't forget to run pip install -r requirement.txt firstly) 59 | 60 | 5. You can select run, debug, and deploy in flow.dag.yaml to complete promptflow debugging. 61 | 62 | ![image](/imgs/03/04.png) 63 | 64 | 6. Run it locally and you can see the chat interface 65 | 66 | 67 | ![image](/imgs/03/05.png) 68 | 69 | 7. Learn how to call the interface through http://localhost:8080/swagger.json 70 | 71 | ![image](/imgs/03/06.png) 72 | 73 | 8. Added to Visual Studio Code Extension 74 | 75 | Install note-fetch 76 | 77 | ```bash 78 | 79 | npm install node-fetch@2 80 | 81 | 82 | ``` 83 | 84 | Update copilotenterprise.js 85 | 86 | ```js 87 | 88 | const fetch = require('node-fetch'); 89 | 90 | ......... 91 | 92 | async function RunPlanner(qa){ 93 | 94 | const myUrl = 'http://127.0.0.1:8080/score'; 95 | const myData = {"question":qa}; 96 | 97 | const response = await fetch(myUrl, { 98 | method: 'POST', 99 | body: JSON.stringify(myData), 100 | }).then((response) => response.json()); 101 | 102 | //console.log(response); 103 | 104 | return response.answer; 105 | 106 | 107 | } 108 | 109 | 110 | ``` 111 | 112 | Change copilotenterprise.js 113 | 114 | 115 | ```js 116 | 117 | const {RunInSemanticKernel,RunPlanner} = require('./enterprisecopilot.js'); 118 | 119 | ......... 120 | 121 | 122 | let webViewProvider={ 123 | resolveWebviewView: (_webviewView , _webviewContex) => { 124 | _webviewView.webview.options={enableScripts:true}; 125 | this.webView = _webviewView; 126 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 127 | this.webView.webview.onDidReceiveMessage( async message => { 128 | switch (message.type) { 129 | case 'addQA': 130 | 131 | const result = await RunPlanner(message.value); //await RunInSemanticKernel(message.value,"Translate"); 132 | const strQA = '🧑:
' + message.value + '
' + '🤖:
' + result + '
'; 133 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 134 | break; 135 | } 136 | }, undefined, context.subscriptions); 137 | } 138 | }; 139 | 140 | 141 | ``` 142 | 143 | Run it 144 | 145 | 146 | ![image](/imgs/03/07.png) 147 | 148 | Great, you can already do more customization work. Of course, this workshop is just your first step, or we are not just using Semantic Kernel, there are more possibilities when combined with Promptflow. 149 | 150 | 151 | -------------------------------------------------------------------------------- /code/03/copilotext/src/extension.js: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | const vscode = require('vscode'); 4 | // const dotnet = require('node-api-dotnet'); 5 | // const initSK = require('./enterprisecopilot.js'); 6 | const {RunInSemanticKernel,RunPlanner} = require('./enterprisecopilot.js'); 7 | // const RunPlanner = require('./enterprisecopilot.js'); 8 | require('./semantic-kernel.js'); 9 | require('./enterprisecopilot.js'); 10 | 11 | // This method is called when your extension is activated 12 | // Your extension is activated the very first time the command is executed 13 | 14 | /** 15 | * @param {vscode.ExtensionContext} context 16 | */ 17 | function activate(context) { 18 | 19 | // Use the console to output diagnostic information (console.log) and errors (console.error) 20 | // This line of code will only be executed once when your extension is activated 21 | console.log('I am your AI assitanst !'); 22 | 23 | let webView; 24 | 25 | let extensionURL = context.extensionUri; 26 | 27 | 28 | let webViewProvider={ 29 | resolveWebviewView: (_webviewView , _webviewContex) => { 30 | _webviewView.webview.options={enableScripts:true}; 31 | this.webView = _webviewView; 32 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 33 | this.webView.webview.onDidReceiveMessage( async message => { 34 | switch (message.type) { 35 | case 'addQA': 36 | 37 | const result = await RunPlanner(message.value); //await RunInSemanticKernel(message.value,"Translate"); 38 | const strQA = '🧑:
' + message.value + '
' + '🤖:
' + result + '
'; 39 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 40 | break; 41 | } 42 | }, undefined, context.subscriptions); 43 | } 44 | }; 45 | 46 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 47 | webviewOptions: { retainContextWhenHidden: true } 48 | })); 49 | 50 | let checkcode_cmd = vscode.commands.registerCommand('copilotext.checkcode', async function () { 51 | 52 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 53 | 54 | const result = await RunInSemanticKernel(selectedText,"Check"); 55 | 56 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 57 | 58 | 59 | }); 60 | 61 | let introcode_cmd = vscode.commands.registerCommand('copilotext.introcode', async function () { 62 | 63 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 64 | 65 | const result = await RunInSemanticKernel(selectedText,"Intro"); 66 | 67 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 68 | }); 69 | 70 | let regencode_cmd = vscode.commands.registerCommand('copilotext.regencode', async function () { 71 | 72 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 73 | 74 | const result = await RunInSemanticKernel(selectedText,"Regencode"); 75 | 76 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 77 | }); 78 | 79 | context.subscriptions.push(checkcode_cmd); 80 | context.subscriptions.push(introcode_cmd); 81 | context.subscriptions.push(regencode_cmd); 82 | 83 | } 84 | 85 | 86 | function initChatViewContent(webview ,extensionURL) { 87 | 88 | 89 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 90 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 91 | 92 | return ` 93 | 94 | 95 | 96 | 97 | 98 | 🤖 Enterprise Copilot Assitant 99 | 146 | 147 | 148 |

🤖 Enterprise Copilot Assitant

149 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

150 | I can do 151 | 156 |

157 |
158 |
159 | 160 | 161 |
162 |
163 | 172 | 173 | `; 174 | 175 | } 176 | 177 | // This method is called when your extension is deactivated 178 | function deactivate() {} 179 | 180 | module.exports = { 181 | activate, 182 | deactivate 183 | } 184 | -------------------------------------------------------------------------------- /code/02/final/copilotext/src/extension.js: -------------------------------------------------------------------------------- 1 | // The module 'vscode' contains the VS Code extensibility API 2 | // Import the module and reference it with the alias vscode in your code below 3 | const vscode = require('vscode'); 4 | // const dotnet = require('node-api-dotnet'); 5 | // const initSK = require('./enterprisecopilot.js'); 6 | const RunInSemanticKernel = require('./enterprisecopilot.js'); 7 | require('./semantic-kernel.js'); 8 | require('./enterprisecopilot.js'); 9 | 10 | // This method is called when your extension is activated 11 | // Your extension is activated the very first time the command is executed 12 | 13 | /** 14 | * @param {vscode.ExtensionContext} context 15 | */ 16 | function activate(context) { 17 | 18 | // Use the console to output diagnostic information (console.log) and errors (console.error) 19 | // This line of code will only be executed once when your extension is activated 20 | console.log('I am your AI assitanst !'); 21 | 22 | let webView; 23 | 24 | let extensionURL = context.extensionUri; 25 | 26 | 27 | let webViewProvider={ 28 | resolveWebviewView: (_webviewView , _webviewContex) => { 29 | _webviewView.webview.options={enableScripts:true}; 30 | this.webView = _webviewView; 31 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 32 | this.webView.webview.onDidReceiveMessage( async message => { 33 | switch (message.type) { 34 | case 'addQA': 35 | 36 | const result = await RunInSemanticKernel(message.value,"Translate"); 37 | const strQA = '🧑:
' + message.value + '
' + '🤖:
' + result + '
'; 38 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 39 | break; 40 | } 41 | }, undefined, context.subscriptions); 42 | } 43 | }; 44 | 45 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 46 | webviewOptions: { retainContextWhenHidden: true } 47 | })); 48 | 49 | let checkcode_cmd = vscode.commands.registerCommand('copilotext.checkcode', async function () { 50 | 51 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 52 | 53 | const result = await RunInSemanticKernel(selectedText,"Check"); 54 | 55 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 56 | 57 | 58 | }); 59 | 60 | let introcode_cmd = vscode.commands.registerCommand('copilotext.introcode', async function () { 61 | 62 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 63 | 64 | const result = await RunInSemanticKernel(selectedText,"Intro"); 65 | 66 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 67 | }); 68 | 69 | let regencode_cmd = vscode.commands.registerCommand('copilotext.regencode', async function () { 70 | 71 | const selectedText = vscode.window.activeTextEditor.document.getText(vscode.window.activeTextEditor.selection); 72 | 73 | const result = await RunInSemanticKernel(selectedText,"Regencode"); 74 | 75 | this.webView.webview.postMessage({ type: 'addCode', value: '🤖:
' + result + '
'}); 76 | }); 77 | 78 | context.subscriptions.push(checkcode_cmd); 79 | context.subscriptions.push(introcode_cmd); 80 | context.subscriptions.push(regencode_cmd); 81 | 82 | } 83 | 84 | 85 | function initChatViewContent(webview ,extensionURL) { 86 | 87 | 88 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 89 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 90 | 91 | return ` 92 | 93 | 94 | 95 | 96 | 97 | 🤖 Enterprise Copilot Assitant 98 | 145 | 146 | 147 |

🤖 Enterprise Copilot Assitant

148 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

149 | I can do 150 | 155 |

156 |
157 |
158 | 159 | 160 |
161 |
162 | 171 | 172 | `; 173 | 174 | } 175 | 176 | // This method is called when your extension is deactivated 177 | function deactivate() {} 178 | 179 | module.exports = { 180 | activate, 181 | deactivate 182 | } 183 | -------------------------------------------------------------------------------- /workshop/01/README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # **Visual Studio Code 插件开发** 2 | 3 | 4 | Visual Studio Code 是一个非常流行的开源开发工具。 通过安装不同的扩展,可以完成不同编程语言的支持、DevOps等相关工作。 作为开发人员,您每天都离不开 Visual Studio Code。 在这里,我们将了解Visual Studio Code Extension是如何开发的。 5 | 6 | ## **环境配置** 7 | 8 | 1. 安装 NodeJS 18+ 9 | 10 | 2. 打开命令行并执行以下命令安装 Visual Studio Code 插件支持 11 | 12 | ```bash 13 | npm install -g yo generator-code 14 | ``` 15 | 16 | 3. 从命令行创建 Visual Studio Code 插件项目 17 | 18 | ```bash 19 | yo code 20 | ``` 21 | 22 | 命令行中将显示以下选项 23 | 24 | ![image](/imgs/01/01.png) 25 | 26 | Visual Studio Code Extensions 支持 TypeScript 和 JavaScript 开发,本次 Workshop 使用 JavaScript。 27 | 28 | 请按照此图片完成设置 29 | 30 | ![image](/imgs/01/02.png) 31 | 32 | 创建完成后,选择Visual Studio Code打开项目 33 | 34 | ![image](/imgs/01/03.png) 35 | 36 | 选择运行,按Ctrl+Shift+P,输入Hello World,如下图,项目创建完成。 37 | 38 | ![image](/imgs/01/04.png) 39 | 40 | 41 | ## **VSCode 插件相关文件** 42 | 43 | ### **package.json** 44 | 45 | 除了与 Visual Studio Code Extension 相关的 node 包外,您还可以通过 package.json 管理与 Visual Studio Code Extension 相关的节点包。 您还可以在此处设置项目文件、响应事件绑定、布局和相关设置,例如 Azure OpenAI 的 Endpoint 和 Key。 46 | 47 | ### **extensions.js** 48 | 49 | 这是 Visual Studio Code 插件的实际逻辑实现。 这是核心文件,默认放置在根目录下,但是我们可以将该文件放置在其他文件夹中,例如设置一个./src文件。 50 | 51 | ![image](/imgs/01/05.png) 52 | 53 | 修改 package.json,在 main 中设置新位置 54 | 55 | 56 | ```json 57 | "activationEvents": [], 58 | "main": "./src/extension.js", 59 | "contributes": { 60 | "commands": [{ 61 | "command": "copilotext.helloWorld", 62 | "title": "Hello World" 63 | }] 64 | } 65 | ``` 66 | 67 | 68 | ## **复制一个 GitHub Copilot Chat 界面** 69 | 70 | ![image](/imgs/01/06.png) 71 | 72 | 您使用过 GitHub Copilot Chat 吗? 你可以一边聊天一边结合自己的业务,完成编写程序的工作。 企业级的副驾驶或者您可能需要类似的界面。 接下来我们开始在 Visual Studio Code Extension 中构建类似的界面。 73 | 74 | 我们知道 Visual Studio Code 是建立在 Electron 框架之上的。 所以本质上该界面是一个WebView。 我们需要进行Visual Studio Code编程,更多的是基于Web UI的实现。 75 | 76 | ### **1. 在 extensions.js 添加 WebView ** 77 | 78 | *添加 initChatViewContent 方法* 79 | 80 | 我们希望模仿 GitHub Copilot Chat 的实现,在左侧菜单上构建一个聊天界面。 我们需要初始化控制激活函数。 我们通过Webview来实现。 我们通过WebViewProvider以及WebView对应的显示事件来设置显示内容。 81 | 82 | 83 | ```javascript 84 | 85 | let webView; 86 | 87 | let extensionURL = context.extensionUri; 88 | 89 | 90 | let webViewProvider={ 91 | resolveWebviewView: (_webviewView , _webviewContex) => { 92 | _webviewView.webview.options={enableScripts:true}; 93 | this.webView = _webviewView; 94 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 95 | this.webView.webview.onDidReceiveMessage(message => { 96 | switch (message.type) { 97 | case 'addQA': 98 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 99 | break; 100 | } 101 | }, undefined, context.subscriptions); 102 | } 103 | }; 104 | 105 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 106 | webviewOptions: { retainContextWhenHidden: true } 107 | })); 108 | 109 | 110 | ``` 111 | 112 | 除了传统的输入框和按钮组合之外,我们还需要通过输入命令的方式与WebView进行交互。 您可以注册相关命令。 113 | 114 | 115 | ```javascript 116 | 117 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 118 | 119 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 120 | }) 121 | 122 | 123 | 124 | 125 | context.subscriptions.push(ask_cmd); 126 | 127 | 128 | ``` 129 | 130 | 以下是完整代码 131 | 132 | ```javascript 133 | 134 | // The module 'vscode' contains the VS Code extensibility API 135 | // Import the module and reference it with the alias vscode in your code below 136 | const vscode = require('vscode'); 137 | 138 | // This method is called when your extension is activated 139 | // Your extension is activated the very first time the command is executed 140 | 141 | /** 142 | * @param {vscode.ExtensionContext} context 143 | */ 144 | function activate(context) { 145 | 146 | console.log('I am your AI assitanst !'); 147 | 148 | let webView; 149 | 150 | let extensionURL = context.extensionUri; 151 | 152 | 153 | let webViewProvider={ 154 | resolveWebviewView: (_webviewView , _webviewContex) => { 155 | _webviewView.webview.options={enableScripts:true}; 156 | this.webView = _webviewView; 157 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 158 | this.webView.webview.onDidReceiveMessage(message => { 159 | switch (message.type) { 160 | case 'addQA': 161 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 162 | break; 163 | } 164 | }, undefined, context.subscriptions); 165 | } 166 | }; 167 | 168 | 169 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 170 | webviewOptions: { retainContextWhenHidden: true } 171 | })); 172 | 173 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 174 | 175 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 176 | }) 177 | 178 | 179 | 180 | 181 | context.subscriptions.push(ask_cmd); 182 | } 183 | 184 | 185 | function initChatViewContent(webview ,extensionURL) { 186 | 187 | 188 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 189 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 190 | 191 | return ` 192 | 193 | 194 | 195 | 196 | 197 | 🤖 Enterprise Copilot Assitant 198 | 245 | 246 | 247 |

🤖 Enterprise Copilot Assitant

248 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

249 | I can do 250 | 255 |

256 |
257 |
258 | 259 | 260 |
261 |
262 | 271 | 272 | `; 273 | 274 | } 275 | 276 | // This method is called when your extension is deactivated 277 | function deactivate() {} 278 | 279 | module.exports = { 280 | activate, 281 | deactivate 282 | } 283 | 284 | 285 | 286 | ``` 287 | 288 | ### **2. 替换 package.json file** 289 | 290 | Visual Studio Code使用JSON进行页面布局,并通过contribute字段绑定相关操作,例如命令、viewContainers和视图操作。 以下是相关代码 291 | 292 | ```json 293 | 294 | 295 | { 296 | "name": "copilotext", 297 | "displayName": "copilotext", 298 | "description": "", 299 | "version": "0.0.1", 300 | "engines": { 301 | "vscode": "^1.81.0" 302 | }, 303 | "categories": [ 304 | "Other" 305 | ], 306 | "activationEvents": [ 307 | ], 308 | "main": "./src/extension.js", 309 | "contributes": { 310 | "commands": [{ 311 | "command": "copilotext.addAskResponse", 312 | "title": "🤖 ask copilot" 313 | }], 314 | "viewsContainers": { 315 | "activitybar": [ 316 | { 317 | "id": "copilotext", 318 | "title": "Enterprise Copilot", 319 | "icon": "media/imgs/icon.png" 320 | } 321 | ] 322 | }, 323 | "views": { 324 | "copilotext": [ 325 | { 326 | "type": "webview", 327 | "id": "copilotext.copilotView", 328 | "name": "EnpterpriseCopilot" 329 | } 330 | ] 331 | } 332 | }, 333 | "scripts": { 334 | "lint": "eslint .", 335 | "pretest": "npm run lint", 336 | "test": "node ./test/runTest.js" 337 | }, 338 | "devDependencies": { 339 | "@types/vscode": "^1.81.0", 340 | "@types/mocha": "^10.0.1", 341 | "@types/node": "16.x", 342 | "eslint": "^8.47.0", 343 | "glob": "^10.3.3", 344 | "mocha": "^10.2.0", 345 | "typescript": "^5.1.6", 346 | "@vscode/test-electron": "^2.3.4" 347 | } 348 | } 349 | 350 | ``` 351 | 352 | 353 | ### **3. 添加 web.js** 354 | 355 | 添加 web.js 到 meida/js 356 | 357 | 358 | ```javascript 359 | 360 | (function () { 361 | 362 | // @ts-ignore 363 | window.addEventListener("message", (event) => { 364 | const message = event.data; 365 | console.log(message); 366 | switch (message.type) { 367 | case "addQA": { 368 | const divTag = document.createElement('div'); 369 | const brTag = document.createElement('br'); 370 | divTag.innerHTML = '🧑:

' + document.getElementById('taAsk').value + '

'; 371 | divTag.innerHTML += '🤖:

' + document.getElementById('taAsk').value + '

'; 372 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 373 | break; 374 | } 375 | } 376 | }); 377 | 378 | 379 | })(); 380 | 381 | ``` 382 | 383 | 384 | 385 | 386 | 387 | ### **3. 再次执行运行和调试** 388 | 389 | 390 | ![image](/imgs/01/07.png) 391 | 392 | 393 | 🎉🎉🎉 您现已完成属于您的 Enterprise Copilot Visual Studio Code 插件 394 | 395 | 396 | ### **4. 与 Enterprise Copilot 进行问答互动** 397 | 398 | 399 | ![image](/imgs/01/08.png) 400 | 401 | 402 | ![image](/imgs/01/09.png) 403 | 404 | 🦸🦸恭喜,您已经初步完成了页面布局的构建。 接下来,我们将继续连接 Azure OpenAI 服务。 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | -------------------------------------------------------------------------------- /workshop/01/README.zh-tw.md: -------------------------------------------------------------------------------- 1 | # **Visual Studio Code 外掛開發** 2 | 3 | 4 | Visual Studio Code 是一個非常流行的開源開發工具。 透過安裝不同的擴充,可以完成不同程式語言的支援、DevOps等相關工作。 作為開發人員,您每天都離不開 Visual Studio Code。 在這裡,我們將瞭解Visual Studio Code Extension是如何開發的。 5 | 6 | ## **環境配置** 7 | 8 | 1. 安裝 NodeJS 18+ 9 | 10 | 2. 開啟命令列並執行以下命令安裝 Visual Studio Code 外掛支援 11 | 12 | ```bash 13 | npm install -g yo generator-code 14 | ``` 15 | 16 | 3. 從命令列建立 Visual Studio Code 外掛專案 17 | 18 | ```bash 19 | yo code 20 | ``` 21 | 22 | 命令列中將顯示以下選項 23 | 24 | ![image](/imgs/01/01.png) 25 | 26 | Visual Studio Code Extensions 支援 TypeScript 和 JavaScript 開發,本次 Workshop 使用 JavaScript。 27 | 28 | 請按照此圖片完成設定 29 | 30 | ![image](/imgs/01/02.png) 31 | 32 | 建立完成後,選擇Visual Studio Code開啟專案 33 | 34 | ![image](/imgs/01/03.png) 35 | 36 | 選擇執行,按Ctrl+Shift+P,輸入Hello World,如下圖,專案建立完成。 37 | 38 | ![image](/imgs/01/04.png) 39 | 40 | 41 | ## **VSCode 外掛相關檔案** 42 | 43 | ### **package.json** 44 | 45 | 除了與 Visual Studio Code Extension 相關的 node 包外,您還可以透過 package.json 管理與 Visual Studio Code Extension 相關的節點套件。 您還可以在此處設定專案檔案、響應事件繫結、佈局和相關設定,例如 Azure OpenAI 的 Endpoint 和 Key。 46 | 47 | ### **extensions.js** 48 | 49 | 這是 Visual Studio Code 外掛的實際邏輯實現。 這是核心檔案,預設放置在根目錄下,但是我們可以將該檔案放置在其他資料夾中,例如設定一個./src檔案。 50 | 51 | ![image](/imgs/01/05.png) 52 | 53 | 修改 package.json,在 main 中設定新位置 54 | 55 | 56 | ```json 57 | "activationEvents": [], 58 | "main": "./src/extension.js", 59 | "contributes": { 60 | "commands": [{ 61 | "command": "copilotext.helloWorld", 62 | "title": "Hello World" 63 | }] 64 | } 65 | ``` 66 | 67 | 68 | ## **複製一個 GitHub Copilot Chat 介面** 69 | 70 | ![image](/imgs/01/06.png) 71 | 72 | 您使用過 GitHub Copilot Chat 嗎? 你可以一邊聊天一邊結合自己的業務,完成編寫程式的工作。 企業級的副駕駛或者您可能需要類似的介面。 接下來我們開始在 Visual Studio Code Extension 中建構類似的介面。 73 | 74 | 我們知道 Visual Studio Code 是建立在 Electron 框架之上的。 所以本質上該介面是一個WebView。 我們需要進行Visual Studio Code程式設計,更多的是基於Web UI的實現。 75 | 76 | ### **1. 在 extensions.js 新增 WebView ** 77 | 78 | *新增 initChatViewContent 方法* 79 | 80 | 我們希望模仿 GitHub Copilot Chat 的實現,在左側選單上建構一個聊天介面。 我們需要初始化控制啟用函式。 我們透過Webview來實現。 我們透過WebViewProvider以及WebView對應的顯示事件來設定顯示內容。 81 | 82 | 83 | ```javascript 84 | 85 | let webView; 86 | 87 | let extensionURL = context.extensionUri; 88 | 89 | 90 | let webViewProvider={ 91 | resolveWebviewView: (_webviewView , _webviewContex) => { 92 | _webviewView.webview.options={enableScripts:true}; 93 | this.webView = _webviewView; 94 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 95 | this.webView.webview.onDidReceiveMessage(message => { 96 | switch (message.type) { 97 | case 'addQA': 98 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 99 | break; 100 | } 101 | }, undefined, context.subscriptions); 102 | } 103 | }; 104 | 105 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 106 | webviewOptions: { retainContextWhenHidden: true } 107 | })); 108 | 109 | 110 | ``` 111 | 112 | 除了傳統的輸入框和按鈕組合之外,我們還需要透過輸入命令的方式與WebView進行互動。 您可以註冊相關命令。 113 | 114 | 115 | ```javascript 116 | 117 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 118 | 119 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 120 | }) 121 | 122 | 123 | 124 | 125 | context.subscriptions.push(ask_cmd); 126 | 127 | 128 | ``` 129 | 130 | 以下是完整程式碼 131 | 132 | ```javascript 133 | 134 | // The module 'vscode' contains the VS Code extensibility API 135 | // Import the module and reference it with the alias vscode in your code below 136 | const vscode = require('vscode'); 137 | 138 | // This method is called when your extension is activated 139 | // Your extension is activated the very first time the command is executed 140 | 141 | /** 142 | * @param {vscode.ExtensionContext} context 143 | */ 144 | function activate(context) { 145 | 146 | console.log('I am your AI assitanst !'); 147 | 148 | let webView; 149 | 150 | let extensionURL = context.extensionUri; 151 | 152 | 153 | let webViewProvider={ 154 | resolveWebviewView: (_webviewView , _webviewContex) => { 155 | _webviewView.webview.options={enableScripts:true}; 156 | this.webView = _webviewView; 157 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 158 | this.webView.webview.onDidReceiveMessage(message => { 159 | switch (message.type) { 160 | case 'addQA': 161 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 162 | break; 163 | } 164 | }, undefined, context.subscriptions); 165 | } 166 | }; 167 | 168 | 169 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 170 | webviewOptions: { retainContextWhenHidden: true } 171 | })); 172 | 173 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 174 | 175 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 176 | }) 177 | 178 | 179 | 180 | 181 | context.subscriptions.push(ask_cmd); 182 | } 183 | 184 | 185 | function initChatViewContent(webview ,extensionURL) { 186 | 187 | 188 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 189 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 190 | 191 | return ` 192 | 193 | 194 | 195 | 196 | 197 | 🤖 Enterprise Copilot Assitant 198 | 245 | 246 | 247 |

🤖 Enterprise Copilot Assitant

248 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

249 | I can do 250 | 255 |

256 |
257 |
258 | 259 | 260 |
261 |
262 | 271 | 272 | `; 273 | 274 | } 275 | 276 | // This method is called when your extension is deactivated 277 | function deactivate() {} 278 | 279 | module.exports = { 280 | activate, 281 | deactivate 282 | } 283 | 284 | 285 | 286 | ``` 287 | 288 | ### **2. 替換 package.json file** 289 | 290 | Visual Studio Code使用JSON進行頁面佈局,並透過contribute欄位繫結相關操作,例如命令、viewContainers和檢視操作。 以下是相關程式碼 291 | 292 | ```json 293 | 294 | 295 | { 296 | "name": "copilotext", 297 | "displayName": "copilotext", 298 | "description": "", 299 | "version": "0.0.1", 300 | "engines": { 301 | "vscode": "^1.81.0" 302 | }, 303 | "categories": [ 304 | "Other" 305 | ], 306 | "activationEvents": [ 307 | ], 308 | "main": "./src/extension.js", 309 | "contributes": { 310 | "commands": [{ 311 | "command": "copilotext.addAskResponse", 312 | "title": "🤖 ask copilot" 313 | }], 314 | "viewsContainers": { 315 | "activitybar": [ 316 | { 317 | "id": "copilotext", 318 | "title": "Enterprise Copilot", 319 | "icon": "media/imgs/icon.png" 320 | } 321 | ] 322 | }, 323 | "views": { 324 | "copilotext": [ 325 | { 326 | "type": "webview", 327 | "id": "copilotext.copilotView", 328 | "name": "EnpterpriseCopilot" 329 | } 330 | ] 331 | } 332 | }, 333 | "scripts": { 334 | "lint": "eslint .", 335 | "pretest": "npm run lint", 336 | "test": "node ./test/runTest.js" 337 | }, 338 | "devDependencies": { 339 | "@types/vscode": "^1.81.0", 340 | "@types/mocha": "^10.0.1", 341 | "@types/node": "16.x", 342 | "eslint": "^8.47.0", 343 | "glob": "^10.3.3", 344 | "mocha": "^10.2.0", 345 | "typescript": "^5.1.6", 346 | "@vscode/test-electron": "^2.3.4" 347 | } 348 | } 349 | 350 | ``` 351 | 352 | 353 | ### **3. 新增 web.js** 354 | 355 | 新增 web.js 到 meida/js 356 | 357 | 358 | ```javascript 359 | 360 | (function () { 361 | 362 | // @ts-ignore 363 | window.addEventListener("message", (event) => { 364 | const message = event.data; 365 | console.log(message); 366 | switch (message.type) { 367 | case "addQA": { 368 | const divTag = document.createElement('div'); 369 | const brTag = document.createElement('br'); 370 | divTag.innerHTML = '🧑:

' + document.getElementById('taAsk').value + '

'; 371 | divTag.innerHTML += '🤖:

' + document.getElementById('taAsk').value + '

'; 372 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 373 | break; 374 | } 375 | } 376 | }); 377 | 378 | 379 | })(); 380 | 381 | ``` 382 | 383 | 384 | 385 | 386 | 387 | ### **3. 再次執行執行和除錯** 388 | 389 | 390 | ![image](/imgs/01/07.png) 391 | 392 | 393 | 🎉🎉🎉 您現已完成屬於您的 Enterprise Copilot Visual Studio Code 外掛 394 | 395 | 396 | ### **4. 與 Enterprise Copilot 進行問答互動** 397 | 398 | 399 | ![image](/imgs/01/08.png) 400 | 401 | 402 | ![image](/imgs/01/09.png) 403 | 404 | 🦸🦸恭喜,您已經初步完成了頁面佈局的建構。 接下來,我們將繼續連線 Azure OpenAI 服務。 405 | 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | -------------------------------------------------------------------------------- /workshop/01/README.md: -------------------------------------------------------------------------------- 1 | # **Visual Studio Code Extension Development** 2 | 3 | 4 | Visual Studio Code is a very popular open source development tool. By installing different extensions, you can complete different programming language support, Devops and other related work. As a developer, you can't live without Visual Studio Code every day. Here, we will learn how the Visual Studio Code Extension is developed. 5 | 6 | ## **Environment** 7 | 8 | 1. Install NodeJS 18+ 9 | 10 | 2. Open the command line and execute the following command to install Visual Studio Code Extension support 11 | 12 | ```bash 13 | npm install -g yo generator-code 14 | ``` 15 | 16 | 3. Create a Visual Studio Code Extension project from the command line 17 | 18 | 19 | ```bash 20 | yo code 21 | ``` 22 | 23 | The following options will be displayed on the command line 24 | 25 | ![image](/imgs/01/01.png) 26 | 27 | Visual Studio Code Extensions support TypeScript and JavaScript development, and the Workshop uses JavaScript. 28 | 29 | Please follow this images to complete the settings 30 | 31 | ![image](/imgs/01/02.png) 32 | 33 | After creation, select Visual Studio Code to open the project 34 | 35 | ![image](/imgs/01/03.png) 36 | 37 | Select Run, press Ctrl + Shift + P, enter Hello World, and as shown below, the project creation is completed. 38 | 39 | ![image](/imgs/01/04.png) 40 | 41 | 42 | ## **VSCode Extension files** 43 | 44 | ### **package.json** 45 | 46 | In addition to the node packages related to Visual Studio Code Extension, you can manage the node packages related to Visual Studio Code Extension through package.json. You can also set the project files, response event binding, layout and related settings such as Azure OpenAI's Endpoint and Key here. 47 | 48 | ### **extensions.js** 49 | 50 | This is the logical implementation of the Visual Studio Code Extension in action. This is the core file and is placed in the root directory by default, but we can place the file in other folders, such as setting a ./src file. 51 | 52 | ![image](/imgs/01/05.png) 53 | 54 | and modify package.json, set new location in main object 55 | 56 | 57 | ```json 58 | "activationEvents": [], 59 | "main": "./src/extension.js", 60 | "contributes": { 61 | "commands": [{ 62 | "command": "copilotext.helloWorld", 63 | "title": "Hello World" 64 | }] 65 | } 66 | ``` 67 | 68 | 69 | ## **Build UI like GitHub Copilot Chat** 70 | 71 | ![image](/imgs/01/06.png) 72 | 73 | Have you used GitHub Copilot Chat? You can combine your business while chatting and complete the work of writing programs. Copilot for enterprise level or you may need a similar interface. Next we start building a similar interface in Visual Studio Code Extension. 74 | 75 | We know that Visual Studio Code is built on the Electron Framework. So essentially the interface is a WebView. We need to program Visual Studio Code, and we are more based on the implementation of Web UI. 76 | 77 | ### **1. Add WebView in extensions.js** 78 | 79 | *add initChatViewContent function* 80 | 81 | We hope to imitate the implementation of GitHub Copilot Chat and build a chat interface on the left menu. We need to initialize the control activation function. We implement it through Webview. We set the display content through WebViewProvider and the corresponding display events of WebView. 82 | 83 | 84 | 85 | ```javascript 86 | 87 | let webView; 88 | 89 | let extensionURL = context.extensionUri; 90 | 91 | 92 | let webViewProvider={ 93 | resolveWebviewView: (_webviewView , _webviewContex) => { 94 | _webviewView.webview.options={enableScripts:true}; 95 | this.webView = _webviewView; 96 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 97 | this.webView.webview.onDidReceiveMessage(message => { 98 | switch (message.type) { 99 | case 'addQA': 100 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 101 | break; 102 | } 103 | }, undefined, context.subscriptions); 104 | } 105 | }; 106 | 107 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 108 | webviewOptions: { retainContextWhenHidden: true } 109 | })); 110 | 111 | 112 | ``` 113 | 114 | In addition to the traditional combination of input boxes and buttons, we need to interact with WebView by entering commands. You can register related commands. 115 | 116 | 117 | ```javascript 118 | 119 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 120 | 121 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 122 | }) 123 | 124 | 125 | 126 | 127 | context.subscriptions.push(ask_cmd); 128 | 129 | 130 | ``` 131 | 132 | The following is the complete code 133 | 134 | ```javascript 135 | 136 | // The module 'vscode' contains the VS Code extensibility API 137 | // Import the module and reference it with the alias vscode in your code below 138 | const vscode = require('vscode'); 139 | 140 | // This method is called when your extension is activated 141 | // Your extension is activated the very first time the command is executed 142 | 143 | /** 144 | * @param {vscode.ExtensionContext} context 145 | */ 146 | function activate(context) { 147 | 148 | console.log('I am your AI assitanst !'); 149 | 150 | let webView; 151 | 152 | let extensionURL = context.extensionUri; 153 | 154 | 155 | let webViewProvider={ 156 | resolveWebviewView: (_webviewView , _webviewContex) => { 157 | _webviewView.webview.options={enableScripts:true}; 158 | this.webView = _webviewView; 159 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 160 | this.webView.webview.onDidReceiveMessage(message => { 161 | switch (message.type) { 162 | case 'addQA': 163 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 164 | break; 165 | } 166 | }, undefined, context.subscriptions); 167 | } 168 | }; 169 | 170 | 171 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 172 | webviewOptions: { retainContextWhenHidden: true } 173 | })); 174 | 175 | const ask_cmd = vscode.commands.registerCommand('copilotext.addAskResponse', async function () { 176 | 177 | this.webView.webview.postMessage({ type: 'addQA', value: '🤖

' }); 178 | }) 179 | 180 | 181 | 182 | 183 | context.subscriptions.push(ask_cmd); 184 | } 185 | 186 | 187 | function initChatViewContent(webview ,extensionURL) { 188 | 189 | 190 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 191 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 192 | 193 | return ` 194 | 195 | 196 | 197 | 198 | 199 | 🤖 Enterprise Copilot Assitant 200 | 247 | 248 | 249 |

🤖 Enterprise Copilot Assitant

250 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

251 | I can do 252 | 257 |

258 |
259 |
260 | 261 | 262 |
263 |
264 | 273 | 274 | `; 275 | 276 | } 277 | 278 | // This method is called when your extension is deactivated 279 | function deactivate() {} 280 | 281 | module.exports = { 282 | activate, 283 | deactivate 284 | } 285 | 286 | 287 | 288 | ``` 289 | 290 | ### **2. Replace package.json file** 291 | 292 | Visual Studio Code uses JSON for page layout and binds related operations through the contribute field, such as commands, viewContainers, and views operations. The following is the relevant code 293 | 294 | 295 | ```json 296 | 297 | 298 | { 299 | "name": "copilotext", 300 | "displayName": "copilotext", 301 | "description": "", 302 | "version": "0.0.1", 303 | "engines": { 304 | "vscode": "^1.81.0" 305 | }, 306 | "categories": [ 307 | "Other" 308 | ], 309 | "activationEvents": [ 310 | ], 311 | "main": "./src/extension.js", 312 | "contributes": { 313 | "commands": [{ 314 | "command": "copilotext.addAskResponse", 315 | "title": "🤖 ask copilot" 316 | }], 317 | "viewsContainers": { 318 | "activitybar": [ 319 | { 320 | "id": "copilotext", 321 | "title": "Enterprise Copilot", 322 | "icon": "media/imgs/icon.png" 323 | } 324 | ] 325 | }, 326 | "views": { 327 | "copilotext": [ 328 | { 329 | "type": "webview", 330 | "id": "copilotext.copilotView", 331 | "name": "EnpterpriseCopilot" 332 | } 333 | ] 334 | } 335 | }, 336 | "scripts": { 337 | "lint": "eslint .", 338 | "pretest": "npm run lint", 339 | "test": "node ./test/runTest.js" 340 | }, 341 | "devDependencies": { 342 | "@types/vscode": "^1.81.0", 343 | "@types/mocha": "^10.0.1", 344 | "@types/node": "16.x", 345 | "eslint": "^8.47.0", 346 | "glob": "^10.3.3", 347 | "mocha": "^10.2.0", 348 | "typescript": "^5.1.6", 349 | "@vscode/test-electron": "^2.3.4" 350 | } 351 | } 352 | 353 | ``` 354 | 355 | 356 | ### **3. Add web.js to src** 357 | 358 | 359 | ```javascript 360 | 361 | (function () { 362 | 363 | // @ts-ignore 364 | window.addEventListener("message", (event) => { 365 | const message = event.data; 366 | console.log(message); 367 | switch (message.type) { 368 | case "addQA": { 369 | const divTag = document.createElement('div'); 370 | const brTag = document.createElement('br'); 371 | divTag.innerHTML = '🧑:

' + document.getElementById('taAsk').value + '

'; 372 | divTag.innerHTML += '🤖:

' + document.getElementById('taAsk').value + '

'; 373 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 374 | break; 375 | } 376 | } 377 | }); 378 | 379 | 380 | })(); 381 | 382 | ``` 383 | 384 | 385 | 386 | 387 | 388 | ### **3. Run Debug again** 389 | 390 | 391 | ![image](/imgs/01/07.png) 392 | 393 | 394 | 🎉🎉🎉 You finished your Enterprise Copilot Visual Studio Code Extensions Now 395 | 396 | 397 | ### **4. QA interaction with your Enterprise Copilot** 398 | 399 | 400 | ![image](/imgs/01/08.png) 401 | 402 | 403 | ![image](/imgs/01/09.png) 404 | 405 | 🦸🦸Congratulations, you have initially completed the construction of the page layout. Next, we will proceed to connect with Azure OpenAI Services. 406 | 407 | 408 | 409 | 410 | 411 | 412 | 413 | 414 | 415 | 416 | 417 | 418 | 419 | -------------------------------------------------------------------------------- /workshop/02/README.zh-cn.md: -------------------------------------------------------------------------------- 1 | # **将 Semantic Kernel 添加到 Visual Studio Code 插件** 2 | 3 | ## **介绍 Semantic Kernel** 4 | 5 | ![image](/imgs/02/sk.png) 6 | 7 | 在 2023 年 5 月的 Microsoft Build 大会上,微软发布了适用于 LLM 应用程序的 Copilot Stack。 为大家通过大模型构建应用指明了方向。 Semantic Kernel 是实现 Copilot Stack 的最佳框架(这有点片面,但不可否认我是 Semantic Kernel 的狂热分子)。 有人问我,为什么不用 LangChain ? 不可否认,LangChain 是一个很好的框架。 它更多地以人工智能的方式解决人工智能问题,但语义内核更好地弥合了代码和提示之间的差距,并且非常适合高度工程化的项目。 如果想了解更多关于 Semantic Kernel 的知识,可以去Semantic Kernel的GitHub进行学习(https://github.com/microsoft/semantic-kernel) 8 | 9 | **如何向 Visual Studio Code 扩展添加 Semantic Kernel 支持** 10 | 11 | 我们知道 Semantic Kernel 已经支持 .NET、Python 和 Java。 但是对于严重依赖 JavaScript 和 TypeScript 的 Visual Studio Code Extension 开发,我们该怎么办呢? 我非常感谢开源世界。 这里是微软官方的https://github.com/microsoft/node-api-dotnet,它可以让我们直接将.NET迁移到NodeJS技术体系上。 本次Workshop参考https://github.com/microsoft/node-api-dotnet完成相关扩展案例。 12 | 13 | 14 | **环境设定** 15 | 16 | 1. git clone https://github.com/microsoft/node-api-dotnet.git 17 | 18 | 2. 在根目录下创建ext文件夹,将 Workshop 第一步的代码复制到该文件夹中 19 | 20 | 3. 根目录下,将examples文件夹中的 Directory.Build.props 和 NuGet.config 复制到ext目录下 21 | 22 | 4. 进入 ext/copilotext 目录,创建 copilotext.csproj 23 | 24 | 5. 将以下代码复制到 copilotext.csproj 25 | 26 | 27 | ```bash 28 | 29 | 30 | 31 | 32 | net8.0 33 | false 34 | $(MSBuildThisFileDirectory)/pkg 35 | bin 36 | esm 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ``` 47 | 48 | 6. 在 Visual Studio Code下打开终端,进入copilotext文件夹,依次输入以下命令 49 | 50 | 51 | 52 | ```bash 53 | dotnet pack ../.. 54 | 55 | dotnet build 56 | 57 | npm install 58 | ``` 59 | 60 | 7. 打开 copilotext 下的 package.json 文件夹并添加以下节点(在 scripts 之前) 61 | 62 | 63 | ```json 64 | 65 | "dependencies": { 66 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet" 67 | }, 68 | 69 | ``` 70 | 71 | 基本环境配置完成。 有几件事需要注意。 72 | 73 | 1. 建议安装 .NET 8 74 | 2. 有时编译时可能会遇到C++问题。 推荐安装Windows C++开发环境。 75 | 76 | 77 | **导入 Semantic Kernel** 78 | 79 | 1. 使用 Visual Studio Code 创建一个新窗口并打开copilotext文件夹 80 | 81 | 2. 在 ackage.json 中添加 Azure OpenAI Service 相关信息(Endpoint、Key、Model) 82 | 83 | 84 | ```json 85 | 86 | "configuration": { 87 | "type": "object", 88 | "title": "copilotext", 89 | "properties": { 90 | "copilotext.endpoint": { 91 | "type": "string", 92 | "default": "Your Azure OpenAI Endpoint", 93 | "description": "Your Azure OpenAI Endpoint", 94 | "order": 0 95 | }, 96 | "copilotext.api_key": { 97 | "type": "string", 98 | "default": "Your Azure OpenAI KEY", 99 | "description": "Your Azure OpenAI KEY", 100 | "order": 1 101 | }, 102 | "copilotext.chatgptmodel": { 103 | "type": "string", 104 | "default": "Your ChatGPT Model", 105 | "description": "Your ChatGPT Model", 106 | "order": 2 107 | } 108 | } 109 | } 110 | 111 | ``` 112 | 113 | 114 | 3. 将 semantic-kernel.js 添加到src文件夹中 115 | 116 | 117 | ```json 118 | 119 | 120 | const fs = require('node:fs'); 121 | const path = require('node:path'); 122 | const dotnet = require('node-api-dotnet'); 123 | 124 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 125 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 126 | 127 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 128 | function resolveAssembly(name) { 129 | console.log(path.join('../bin', name + '.dll')); 130 | return path.join(__dirname,'../bin', name + '.dll'); 131 | } 132 | 133 | dotnet.addListener('resolving', (name) => { 134 | const filePath = resolveAssembly(name); 135 | if (fs.existsSync(filePath)) dotnet.load(filePath); 136 | }); 137 | 138 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 139 | dotnet.load(resolveAssembly(skAssemblyName)); 140 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 141 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); 142 | 143 | ``` 144 | 145 | 4. 在copilotext 目录中新建 skills 文件夹,在 skill 目录中添加CodeSkill 文件夹,然后在 docsskill 目录中添加 Translate 文件夹。 146 | 147 | 5. 在 translate 目录下添加 skprompt.txt 和 config.json 148 | 149 | skprompt.txt 150 | 151 | ```txt 152 | 153 | You are a professional translator, help me translate the {{$input}} into Chinese 154 | 155 | [INPUT] 156 | Hi 157 | [END INPUT] 158 | [OUTPUT] 159 | 你好 160 | [END OUTPUT] 161 | [INPUT] 162 | {{$input}} 163 | [END INPUT] 164 | 165 | ``` 166 | 167 | config.json 168 | 169 | ```json 170 | 171 | { 172 | "schema": 1, 173 | "type": "completion", 174 | "description": "Translates English to Chinese", 175 | "completion": { 176 | "max_tokens": 1300, 177 | "temperature": 0.3, 178 | "presence_penalty": 0.0, 179 | "frequency_penalty": 0.0 180 | } 181 | } 182 | 183 | ``` 184 | 185 | 6. 在 src 文件夹中添加 enterprise-copilot.js 186 | 187 | 188 | ```js 189 | 190 | const vscode = require('vscode'); 191 | const path = require('node:path'); 192 | const dotnet = require('node-api-dotnet'); 193 | require('./semantic-kernel.js'); 194 | 195 | 196 | const SK = dotnet.Microsoft.SemanticKernel; 197 | const config = vscode.workspace.getConfiguration('copilotext'); 198 | const endPoint = config.get('endpoint'); 199 | const apiKey = config.get('api_key'); 200 | const gptModel = config.get('chatgptmodel'); 201 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 202 | const pluginsDirectory = path.join(__dirname,'../plugins'); 203 | const plugins = ['CodePlugin']; 204 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 205 | 206 | 207 | 208 | 209 | async function CheckCodeBySK(code,style) { 210 | 211 | const codeFunction = code_plugin.get(style); 212 | 213 | const context_variable = new SK.Orchestration.ContextVariables(code); 214 | 215 | const context = new SK.Orchestration.SKContext(context_variable); 216 | 217 | const answer = await codeFunction.InvokeAsync(context); 218 | 219 | 220 | return answer.ToString(); 221 | 222 | } 223 | 224 | 225 | module.exports = CheckCodeBySK; 226 | 227 | 228 | ``` 229 | 230 | 7. Update extension.js & web.js file 231 | 232 | extension.js 233 | 234 | ```js 235 | 236 | const vscode = require('vscode'); 237 | const RunInSemanticKernel = require('./enterprisecopilot.js'); 238 | require('./semantic-kernel.js'); 239 | require('./enterprisecopilot.js'); 240 | 241 | 242 | /** 243 | * @param {vscode.ExtensionContext} context 244 | */ 245 | function activate(context) { 246 | 247 | // Use the console to output diagnostic information (console.log) and errors (console.error) 248 | // This line of code will only be executed once when your extension is activated 249 | console.log('I am your AI assitanst !'); 250 | 251 | let webView; 252 | 253 | let extensionURL = context.extensionUri; 254 | 255 | 256 | let webViewProvider={ 257 | resolveWebviewView: (_webviewView , _webviewContex) => { 258 | _webviewView.webview.options={enableScripts:true}; 259 | this.webView = _webviewView; 260 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 261 | this.webView.webview.onDidReceiveMessage( async message => { 262 | switch (message.type) { 263 | case 'addQA': 264 | 265 | const result = await RunInSemanticKernel(message.value,"Translate"); 266 | const strQA = '🧑:

' + message.value + '

' + '🤖:

' + result + '

'; 267 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 268 | break; 269 | } 270 | }, undefined, context.subscriptions); 271 | } 272 | }; 273 | 274 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 275 | webviewOptions: { retainContextWhenHidden: true } 276 | })); 277 | } 278 | 279 | 280 | function initChatViewContent(webview ,extensionURL) { 281 | 282 | 283 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 284 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 285 | 286 | return ` 287 | 288 | 289 | 290 | 291 | 292 | 🤖 Enterprise Copilot Assitant 293 | 340 | 341 | 342 |

🤖 Enterprise Copilot Assitant

343 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

344 | I can do 345 | 350 |

351 |
352 |
353 | 354 | 355 |
356 |
357 | 366 | 367 | `; 368 | 369 | } 370 | 371 | // This method is called when your extension is deactivated 372 | function deactivate() {} 373 | 374 | module.exports = { 375 | activate, 376 | deactivate 377 | } 378 | 379 | 380 | ``` 381 | 382 | web.js 383 | 384 | ```js 385 | 386 | (function () { 387 | 388 | // @ts-ignore 389 | window.addEventListener("message", (event) => { 390 | const message = event.data; 391 | console.log(message); 392 | switch (message.type) { 393 | case "addQA": { 394 | const divTag = document.createElement('div'); 395 | const brTag = document.createElement('br'); 396 | divTag.innerHTML = message.value; 397 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 398 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 399 | document.getElementById("taAsk").value = ""; 400 | break; 401 | } 402 | } 403 | }); 404 | 405 | 406 | })(); 407 | 408 | ``` 409 | 410 | 8. 再次运行,哦你的Enterprise GitHub Copilot现在可以成为你的翻译了 [完整代码](./code/02/kickoff) 411 | 412 | 413 | ![image](/imgs/02/translate.png) 414 | 415 | 416 | 但这是一个代码编辑器。 我们需要的不仅仅是一名翻译。 我们可以通过添加不同的Skill来增强我们的企业级编程能力。 如果您有兴趣,可以运行[code/02/final](./code/02/final)文件夹中的项目。 当您打开代码并单击鼠标右键时,您可以添加代码分析、检查和重构功能。 或者这是您最终的企业级 Copilot 实施吗? 417 | 418 | 419 | ![image](/imgs/02/code.png) 420 | 421 | 🦸🦸 恭喜!!!您已经学会了自定义一个类似于 GitHub Copilot Chat 的 Visual Studio Code Extension。 接下来我们将定制企业级功能。 422 | 423 | 424 | -------------------------------------------------------------------------------- /workshop/02/README.zh-tw.md: -------------------------------------------------------------------------------- 1 | # **將 Semantic Kernel 新增到 Visual Studio Code 外掛** 2 | 3 | ## **介紹 Semantic Kernel** 4 | 5 | ![image](/imgs/02/sk.png) 6 | 7 | 在 2023 年 5 月的 Microsoft Build 大會上,微軟釋出了適用於 LLM 應用程式的 Copilot Stack。 為大家透過大模型建構應用指明瞭方向。 Semantic Kernel 是實現 Copilot Stack 的最佳框架(這有點片面,但不可否認我是 Semantic Kernel 的狂熱分子)。 有人問我,為什麼不用 LangChain ? 不可否認,LangChain 是一個很好的框架。 它更多地以人工智慧的方式解決人工智慧問題,但語義核心更好地彌合了程式碼和提示之間的差距,並且非常適合高度工程化的專案。 如果想了解更多關於 Semantic Kernel 的知識,可以去Semantic Kernel的GitHub進行學習(https://github.com/microsoft/semantic-kernel) 8 | 9 | **如何向 Visual Studio Code 擴充新增 Semantic Kernel 支援** 10 | 11 | 我們知道 Semantic Kernel 已經支援 .NET、Python 和 Java。 但是對於嚴重依賴 JavaScript 和 TypeScript 的 Visual Studio Code Extension 開發,我們該怎麼辦呢? 我非常感謝開源世界。 這裡是微軟官方的https://github.com/microsoft/node-api-dotnet,它可以讓我們直接將.NET遷移到NodeJS技術體系上。 本次Workshop參考https://github.com/microsoft/node-api-dotnet完成相關擴充案例。 12 | 13 | 14 | **環境設定** 15 | 16 | 1. git clone https://github.com/microsoft/node-api-dotnet.git 17 | 18 | 2. 在根目錄下建立ext資料夾,將 Workshop 第一步的程式碼複製到該資料夾中 19 | 20 | 3. 根目錄下,將examples資料夾中的 Directory.Build.props 和 NuGet.config 複製到ext目錄下 21 | 22 | 4. 進入 ext/copilotext 目錄,建立 copilotext.csproj 23 | 24 | 5. 將以下程式碼複製到 copilotext.csproj 25 | 26 | 27 | ```bash 28 | 29 | 30 | 31 | 32 | net8.0 33 | false 34 | $(MSBuildThisFileDirectory)/pkg 35 | bin 36 | esm 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ``` 47 | 48 | 6. 在 Visual Studio Code下開啟終端,進入copilotext資料夾,依次輸入以下命令 49 | 50 | 51 | 52 | ```bash 53 | dotnet pack ../.. 54 | 55 | dotnet build 56 | 57 | npm install 58 | ``` 59 | 60 | 7. 開啟 copilotext 下的 package.json 資料夾並新增以下節點(在 scripts 之前) 61 | 62 | 63 | ```json 64 | 65 | "dependencies": { 66 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet" 67 | }, 68 | 69 | ``` 70 | 71 | 基本環境配置完成。 有幾件事需要注意。 72 | 73 | 1. 建議安裝 .NET 8 74 | 2. 有時編譯時可能會遇到C++問題。 推薦安裝Windows C++開發環境。 75 | 76 | 77 | **匯入 Semantic Kernel** 78 | 79 | 1. 使用 Visual Studio Code 建立一個新視窗並開啟copilotext資料夾 80 | 81 | 2. 在 ackage.json 中新增 Azure OpenAI Service 相關資訊(Endpoint、Key、Model) 82 | 83 | 84 | ```json 85 | 86 | "configuration": { 87 | "type": "object", 88 | "title": "copilotext", 89 | "properties": { 90 | "copilotext.endpoint": { 91 | "type": "string", 92 | "default": "Your Azure OpenAI Endpoint", 93 | "description": "Your Azure OpenAI Endpoint", 94 | "order": 0 95 | }, 96 | "copilotext.api_key": { 97 | "type": "string", 98 | "default": "Your Azure OpenAI KEY", 99 | "description": "Your Azure OpenAI KEY", 100 | "order": 1 101 | }, 102 | "copilotext.chatgptmodel": { 103 | "type": "string", 104 | "default": "Your ChatGPT Model", 105 | "description": "Your ChatGPT Model", 106 | "order": 2 107 | } 108 | } 109 | } 110 | 111 | ``` 112 | 113 | 114 | 3. 將 semantic-kernel.js 新增到src資料夾中 115 | 116 | 117 | ```json 118 | 119 | 120 | const fs = require('node:fs'); 121 | const path = require('node:path'); 122 | const dotnet = require('node-api-dotnet'); 123 | 124 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 125 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 126 | 127 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 128 | function resolveAssembly(name) { 129 | console.log(path.join('../bin', name + '.dll')); 130 | return path.join(__dirname,'../bin', name + '.dll'); 131 | } 132 | 133 | dotnet.addListener('resolving', (name) => { 134 | const filePath = resolveAssembly(name); 135 | if (fs.existsSync(filePath)) dotnet.load(filePath); 136 | }); 137 | 138 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 139 | dotnet.load(resolveAssembly(skAssemblyName)); 140 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 141 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); 142 | 143 | ``` 144 | 145 | 4. 在copilotext 目錄中新建 skills 資料夾,在 skill 目錄中新增CodeSkill 資料夾,然後在 docsskill 目錄中新增 Translate 資料夾。 146 | 147 | 5. 在 translate 目錄下新增 skprompt.txt 和 config.json 148 | 149 | skprompt.txt 150 | 151 | ```txt 152 | 153 | You are a professional translator, help me translate the {{$input}} into Chinese 154 | 155 | [INPUT] 156 | Hi 157 | [END INPUT] 158 | [OUTPUT] 159 | 你好 160 | [END OUTPUT] 161 | [INPUT] 162 | {{$input}} 163 | [END INPUT] 164 | 165 | ``` 166 | 167 | config.json 168 | 169 | ```json 170 | 171 | { 172 | "schema": 1, 173 | "type": "completion", 174 | "description": "Translates English to Chinese", 175 | "completion": { 176 | "max_tokens": 1300, 177 | "temperature": 0.3, 178 | "presence_penalty": 0.0, 179 | "frequency_penalty": 0.0 180 | } 181 | } 182 | 183 | ``` 184 | 185 | 6. 在 src 資料夾中新增 enterprise-copilot.js 186 | 187 | 188 | ```js 189 | 190 | const vscode = require('vscode'); 191 | const path = require('node:path'); 192 | const dotnet = require('node-api-dotnet'); 193 | require('./semantic-kernel.js'); 194 | 195 | 196 | const SK = dotnet.Microsoft.SemanticKernel; 197 | const config = vscode.workspace.getConfiguration('copilotext'); 198 | const endPoint = config.get('endpoint'); 199 | const apiKey = config.get('api_key'); 200 | const gptModel = config.get('chatgptmodel'); 201 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 202 | const pluginsDirectory = path.join(__dirname,'../plugins'); 203 | const plugins = ['CodePlugin']; 204 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 205 | 206 | 207 | 208 | async function CheckCodeBySK(code,style) { 209 | 210 | const codeFunction = code_plugin.get(style); 211 | 212 | const context_variable = new SK.Orchestration.ContextVariables(code); 213 | 214 | const context = new SK.Orchestration.SKContext(context_variable); 215 | 216 | const answer = await codeFunction.InvokeAsync(context); 217 | 218 | 219 | return answer.ToString(); 220 | 221 | } 222 | 223 | 224 | module.exports = CheckCodeBySK; 225 | 226 | 227 | ``` 228 | 229 | 7. Update extension.js & web.js file 230 | 231 | extension.js 232 | 233 | ```js 234 | 235 | const vscode = require('vscode'); 236 | const RunInSemanticKernel = require('./enterprisecopilot.js'); 237 | require('./semantic-kernel.js'); 238 | require('./enterprisecopilot.js'); 239 | 240 | 241 | /** 242 | * @param {vscode.ExtensionContext} context 243 | */ 244 | function activate(context) { 245 | 246 | // Use the console to output diagnostic information (console.log) and errors (console.error) 247 | // This line of code will only be executed once when your extension is activated 248 | console.log('I am your AI assitanst !'); 249 | 250 | let webView; 251 | 252 | let extensionURL = context.extensionUri; 253 | 254 | 255 | let webViewProvider={ 256 | resolveWebviewView: (_webviewView , _webviewContex) => { 257 | _webviewView.webview.options={enableScripts:true}; 258 | this.webView = _webviewView; 259 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 260 | this.webView.webview.onDidReceiveMessage( async message => { 261 | switch (message.type) { 262 | case 'addQA': 263 | 264 | const result = await RunInSemanticKernel(message.value,"Translate"); 265 | const strQA = '🧑:

' + message.value + '

' + '🤖:

' + result + '

'; 266 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 267 | break; 268 | } 269 | }, undefined, context.subscriptions); 270 | } 271 | }; 272 | 273 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 274 | webviewOptions: { retainContextWhenHidden: true } 275 | })); 276 | } 277 | 278 | 279 | function initChatViewContent(webview ,extensionURL) { 280 | 281 | 282 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 283 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 284 | 285 | return ` 286 | 287 | 288 | 289 | 290 | 291 | 🤖 Enterprise Copilot Assitant 292 | 339 | 340 | 341 |

🤖 Enterprise Copilot Assitant

342 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

343 | I can do 344 | 349 |

350 |
351 |
352 | 353 | 354 |
355 |
356 | 365 | 366 | `; 367 | 368 | } 369 | 370 | // This method is called when your extension is deactivated 371 | function deactivate() {} 372 | 373 | module.exports = { 374 | activate, 375 | deactivate 376 | } 377 | 378 | 379 | ``` 380 | 381 | web.js 382 | 383 | ```js 384 | 385 | (function () { 386 | 387 | // @ts-ignore 388 | window.addEventListener("message", (event) => { 389 | const message = event.data; 390 | console.log(message); 391 | switch (message.type) { 392 | case "addQA": { 393 | const divTag = document.createElement('div'); 394 | const brTag = document.createElement('br'); 395 | divTag.innerHTML = message.value; 396 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 397 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 398 | document.getElementById("taAsk").value = ""; 399 | break; 400 | } 401 | } 402 | }); 403 | 404 | 405 | })(); 406 | 407 | ``` 408 | 409 | 8. 再次執行,哦你的Enterprise GitHub Copilot現在可以成為你的翻譯了 [完整程式碼](./code/02/kickoff) 410 | 411 | 412 | ![image](/imgs/02/translate.png) 413 | 414 | 415 | 但這是一個程式碼編輯器。 我們需要的不僅僅是一名翻譯。 我們可以透過新增不同的Skill來增強我們的企業級程式設計能力。 如果您有興趣,可以執行[code/02/final](./code/02/final)資料夾中的專案。 當您開啟程式碼並單擊滑鼠右鍵時,您可以新增程式碼分析、檢查和重構功能。 或者這是您最終的企業級 Copilot 實施嗎? 416 | 417 | 418 | ![image](/imgs/02/code.png) 419 | 420 | 🦸🦸 恭喜!!!您已經學會了自訂一個類似於 GitHub Copilot Chat 的 Visual Studio Code Extension。 接下來我們將客製企業級功能。 421 | 422 | 423 | -------------------------------------------------------------------------------- /workshop/02/README.md: -------------------------------------------------------------------------------- 1 | # **Add Semantic Kernel to Visual Studio Code Extension** 2 | 3 | ## **Introduction Semantic Kernel** 4 | 5 | ![image](/imgs/02/sk.png) 6 | 7 | At Microsoft Build in May 2023, Microsoft released Copilot Stack for LLM applications. It pointed out the direction for everyone to build applications through large models. Semantic Kernel is the best framework to implement Copilot Stack (this is a bit one-sided, but I am undeniably a Semantic Kernel fanatic). Someone asked me, why not LangChain? It is undeniable that LangChain is a good framework. It solves AI problems more in an AI way, but Semantic Kernel better bridges the gap between code and prompts, and is very good for highly engineered projects. role. If you want to learn more about Semantic Kernel, you can go to Semantic Kernel’s GitHub to learn (https://github.com/microsoft/semantic-kernel) 8 | 9 | **How to add Semantic Kernel support to a Visual Studio Code extension** 10 | 11 | We know that Semantic Kernel already supports .NET, Python, and Java. But for the development of Visual Studio Code Extension that relies heavily on JavaScript and TypeScript, what should we do? I am very grateful to the open source world. Here is Microsoft’s official https://github.com/microsoft/node-api-dotnet, which allows us to directly migrate .NET to the NodeJS technology system. This Workshop refers to https://github.com/microsoft/node-api-dotnet to complete related extension cases. 12 | 13 | 14 | **Environment settings** 15 | 16 | 1. git clone https://github.com/microsoft/node-api-dotnet.git 17 | 18 | 2. In the root directory, create the ext folder and copy the code from the first step of the Workshop into the folder 19 | 20 | 3. In the root directory, copy Directory.Build.props and NuGet.config in the examples folder to the ext directory 21 | 22 | 4. Enter the ext/copilotext directory and create copilotext.csproj 23 | 24 | 5. Copy the following code to copilotext.csproj 25 | 26 | 27 | ```bash 28 | 29 | 30 | 31 | 32 | net8.0 33 | false 34 | $(MSBuildThisFileDirectory)/pkg 35 | bin 36 | esm 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | ``` 47 | 48 | 6. Open the terminal under Visual Studio Code, goto the copilotext folder, and enter the following commands in sequence 49 | 50 | 51 | 52 | ```bash 53 | dotnet pack ../.. 54 | 55 | dotnet build 56 | 57 | npm install 58 | ``` 59 | 60 | 7. Open the package.json folder under copilotext and add the following nodes(before "scripts") 61 | 62 | 63 | ```json 64 | 65 | "dependencies": { 66 | "node-api-dotnet": "file:../../out/pkg/node-api-dotnet" 67 | }, 68 | 69 | ``` 70 | 71 | The basic environment configuration is complete. There are a few things to pay attention to. 72 | 73 | 1. It is recommended to install .NET 8 74 | 2. Sometimes you may encounter C++ problems during compilation. It is recommended to install the Windows C++ development environment. 75 | 76 | 77 | **Import Semantic Kernel** 78 | 79 | 1. Create a new window using Visual Studio Code and open the copilotext folder 80 | 81 | 2. Add Azure OpenAI Service related information in package.json ( Endpoint, Key , Model) 82 | 83 | 84 | ```json 85 | 86 | "configuration": { 87 | "type": "object", 88 | "title": "copilotext", 89 | "properties": { 90 | "copilotext.endpoint": { 91 | "type": "string", 92 | "default": "Your Azure OpenAI Endpoint", 93 | "description": "Your Azure OpenAI Endpoint", 94 | "order": 0 95 | }, 96 | "copilotext.api_key": { 97 | "type": "string", 98 | "default": "Your Azure OpenAI KEY", 99 | "description": "Your Azure OpenAI KEY", 100 | "order": 1 101 | }, 102 | "copilotext.chatgptmodel": { 103 | "type": "string", 104 | "default": "Your ChatGPT Model", 105 | "description": "Your ChatGPT Model", 106 | "order": 2 107 | } 108 | } 109 | } 110 | 111 | ``` 112 | 113 | 114 | 3. Add semantic-kernel.js to the src folder 115 | 116 | 117 | ```json 118 | 119 | 120 | const fs = require('node:fs'); 121 | const path = require('node:path'); 122 | const dotnet = require('node-api-dotnet'); 123 | 124 | const skAssemblyName = 'Microsoft.SemanticKernel.Core'; 125 | const skOpenAIAssemblyName = 'Microsoft.SemanticKernel.Connectors.AI.OpenAI'; 126 | 127 | /** All assemblies are resolved from the bin directory, where they were copied by MSBuild. */ 128 | function resolveAssembly(name) { 129 | console.log(path.join('../bin', name + '.dll')); 130 | return path.join(__dirname,'../bin', name + '.dll'); 131 | } 132 | 133 | dotnet.addListener('resolving', (name) => { 134 | const filePath = resolveAssembly(name); 135 | if (fs.existsSync(filePath)) dotnet.load(filePath); 136 | }); 137 | 138 | /** @type import('../bin/Microsoft.SemanticKernel.Core') */ 139 | dotnet.load(resolveAssembly(skAssemblyName)); 140 | /** @type import('../bin/Microsoft.SemanticKernel.Connectors.AI.OpenAI') */ 141 | dotnet.load(resolveAssembly(skOpenAIAssemblyName)); 142 | 143 | ``` 144 | 145 | 4. Create a new skills folder in the copilotext directory, add the CodeSkill folder in the skill directory, and then add the Translate folder in the docsskill directory. 146 | 147 | 5. Add skprompt.txt and config.json in the translate directory 148 | 149 | skprompt.txt 150 | 151 | ```txt 152 | 153 | You are a professional translator, help me translate the {{$input}} into Chinese 154 | 155 | [INPUT] 156 | Hi 157 | [END INPUT] 158 | [OUTPUT] 159 | 你好 160 | [END OUTPUT] 161 | [INPUT] 162 | {{$input}} 163 | [END INPUT] 164 | 165 | ``` 166 | 167 | config.json 168 | 169 | ```json 170 | 171 | { 172 | "schema": 1, 173 | "type": "completion", 174 | "description": "Translates English to Chinese", 175 | "completion": { 176 | "max_tokens": 1300, 177 | "temperature": 0.3, 178 | "presence_penalty": 0.0, 179 | "frequency_penalty": 0.0 180 | } 181 | } 182 | 183 | ``` 184 | 185 | 6. Add enterprise-copilot.js in src folder 186 | 187 | 188 | ```js 189 | 190 | const vscode = require('vscode'); 191 | const path = require('node:path'); 192 | const dotnet = require('node-api-dotnet'); 193 | require('./semantic-kernel.js'); 194 | 195 | 196 | const SK = dotnet.Microsoft.SemanticKernel; 197 | const config = vscode.workspace.getConfiguration('copilotext'); 198 | const endPoint = config.get('endpoint'); 199 | const apiKey = config.get('api_key'); 200 | const gptModel = config.get('chatgptmodel'); 201 | const kernel = SK.OpenAIKernelBuilderExtensions.WithAzureOpenAIChatCompletionService(SK.Kernel.Builder, gptModel,endPoint, apiKey).Build(); 202 | const pluginsDirectory = path.join(__dirname,'../plugins'); 203 | const plugins = ['CodePlugin']; 204 | const code_plugin = SK.KernelSemanticFunctionExtensions.ImportSemanticSkillFromDirectory(kernel,pluginsDirectory,plugins); 205 | 206 | 207 | 208 | async function CheckCodeBySK(code,style) { 209 | 210 | const codeFunction = code_plugin.get(style); 211 | 212 | const context_variable = new SK.Orchestration.ContextVariables(code); 213 | 214 | const context = new SK.Orchestration.SKContext(context_variable); 215 | 216 | const answer = await codeFunction.InvokeAsync(context); 217 | 218 | 219 | return answer.ToString(); 220 | 221 | } 222 | 223 | 224 | module.exports = CheckCodeBySK; 225 | 226 | 227 | ``` 228 | 229 | 7. Update extension.js & web.js file 230 | 231 | extension.js 232 | 233 | ```js 234 | 235 | const vscode = require('vscode'); 236 | const RunInSemanticKernel = require('./enterprisecopilot.js'); 237 | require('./semantic-kernel.js'); 238 | require('./enterprisecopilot.js'); 239 | 240 | 241 | /** 242 | * @param {vscode.ExtensionContext} context 243 | */ 244 | function activate(context) { 245 | 246 | // Use the console to output diagnostic information (console.log) and errors (console.error) 247 | // This line of code will only be executed once when your extension is activated 248 | console.log('I am your AI assitanst !'); 249 | 250 | let webView; 251 | 252 | let extensionURL = context.extensionUri; 253 | 254 | 255 | let webViewProvider={ 256 | resolveWebviewView: (_webviewView , _webviewContex) => { 257 | _webviewView.webview.options={enableScripts:true}; 258 | this.webView = _webviewView; 259 | this.webView.webview.html = initChatViewContent(this.webView,extensionURL); 260 | this.webView.webview.onDidReceiveMessage( async message => { 261 | switch (message.type) { 262 | case 'addQA': 263 | 264 | const result = await RunInSemanticKernel(message.value,"Translate"); 265 | const strQA = '🧑:

' + message.value + '

' + '🤖:

' + result + '

'; 266 | this.webView.webview.postMessage({ type: 'addQA', value: strQA }); 267 | break; 268 | } 269 | }, undefined, context.subscriptions); 270 | } 271 | }; 272 | 273 | context.subscriptions.push(vscode.window.registerWebviewViewProvider('copilotext.copilotView' , webViewProvider, { 274 | webviewOptions: { retainContextWhenHidden: true } 275 | })); 276 | } 277 | 278 | 279 | function initChatViewContent(webview ,extensionURL) { 280 | 281 | 282 | const imgUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'imgs', 'icon.png')); 283 | const jsUri = webview.webview.asWebviewUri(vscode.Uri.joinPath(extensionURL, 'media', 'js', 'web.js')); 284 | 285 | return ` 286 | 287 | 288 | 289 | 290 | 291 | 🤖 Enterprise Copilot Assitant 292 | 339 | 340 | 341 |

🤖 Enterprise Copilot Assitant

342 |

I am your enterprise AI assistant, helping you coding and improve work efficiency

343 | I can do 344 | 349 |

350 |
351 |
352 | 353 | 354 |
355 |
356 | 365 | 366 | `; 367 | 368 | } 369 | 370 | // This method is called when your extension is deactivated 371 | function deactivate() {} 372 | 373 | module.exports = { 374 | activate, 375 | deactivate 376 | } 377 | 378 | 379 | ``` 380 | 381 | web.js 382 | 383 | ```js 384 | 385 | (function () { 386 | 387 | // @ts-ignore 388 | window.addEventListener("message", (event) => { 389 | const message = event.data; 390 | console.log(message); 391 | switch (message.type) { 392 | case "addQA": { 393 | const divTag = document.createElement('div'); 394 | const brTag = document.createElement('br'); 395 | divTag.innerHTML = message.value; 396 | // divTag.innerHTML += '🤖:

' + message.value + message.value + '

'; 397 | document.getElementById("answer").appendChild(divTag).appendChild(brTag); 398 | document.getElementById("taAsk").value = ""; 399 | break; 400 | } 401 | } 402 | }); 403 | 404 | 405 | })(); 406 | 407 | ``` 408 | 409 | 8. Run again , oh Your Enterprise GitHub Copilot can be your translator now [Download Code](./code/02/kickoff) 410 | 411 | 412 | ![image](/imgs/02/translate.png) 413 | 414 | 415 | But this is a code editor. We need more than just a translator. We can enhance our enterprise-level programming capabilities by adding different Skills. If you are interested, you can run the project in the [code/02/final](./code/02/final) folder. When you open the code and right-click the mouse, you can add code analysis, inspection, and refactoring capabilities. Or is this your ultimate enterprise-grade Copilot implementation? 416 | 417 | 418 | ![image](/imgs/02/code.png) 419 | 420 | 🦸🦸 Congratulations !!! You have learned to customize a Visual Studio Code Extension similar to GitHub Copilot Chat. Next we will customize enterprise-level functions. 421 | 422 | 423 | --------------------------------------------------------------------------------