From 22092632fff341106f2dd786c6d7d70e626b1109 Mon Sep 17 00:00:00 2001 From: Silas Marvin <19626586+SilasMarvin@users.noreply.github.com> Date: Tue, 28 May 2024 16:27:50 -0700 Subject: [PATCH] Cleanup vscode plugin --- .gitignore | 1 + README.md | 13 +++- editors/vscode/package.json | 104 +-------------------------- editors/vscode/src/index.ts | 137 +++++++++++++++++++++++++++++++++--- 4 files changed, 143 insertions(+), 112 deletions(-) diff --git a/.gitignore b/.gitignore index 348c3e0..ec779b4 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules out dist lsp-ai.log +.vsix diff --git a/README.md b/README.md index b8ff9c7..b816052 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # LSP-AI -LSP-AI is an open source language server that performs completion with large language models. Because it is a language server, it works with any editor that has LSP support. +LSP-AI is an open source language server that serves as a backend for performing completion with large language models and soon other AI powered functionality. Because it is a language server, it works with any editor that has LSP support. A short list of a few of the editors it works with: - VS Code @@ -10,3 +10,14 @@ A short list of a few of the editors it works with: - Sublime It works with many many many more editors. + +See the wiki for instructions on: +- [Installation](https://github.com/SilasMarvin/lsp-ai/wiki/Installation) +- [Configuration](https://github.com/SilasMarvin/lsp-ai/wiki/Configuration) +- [Plugins](https://github.com/SilasMarvin/lsp-ai/wiki/Plugins) +- [Server Capabilities](https://github.com/SilasMarvin/lsp-ai/wiki/Server-Capabilities-and-Functions) +- [and more](https://github.com/SilasMarvin/lsp-ai/wiki) + +# The Case for LSP-AI + + diff --git a/editors/vscode/package.json b/editors/vscode/package.json index bcdda98..21be278 100644 --- a/editors/vscode/package.json +++ b/editors/vscode/package.json @@ -31,112 +31,12 @@ "properties": { "lsp-ai.serverConfiguration": { "type": "object", - "default": { - "memory": { - "file_store": {} - }, - "models": { - "model1": { - "type": "openai", - "chat_endpoint": "https://api.openai.com/v1/chat/completions", - "model": "gpt-4o", - "auth_token_env_var_name": "OPENAI_API_KEY" - } - } - }, + "default": {}, "description": "JSON configuration for LSP-AI language server" }, "lsp-ai.generationConfiguration": { "type": "object", - "default": { - "model": "model1", - "parameters": { - "max_tokens": 128, - "max_context": 1024, - "messages": [ - { - "role": "system", - "content": "Instructions:\n- You are an AI programming assistant.\n- Given a piece of code with the cursor location marked by \"\", replace \"\" with the correct code or comment.\n- First, think step-by-step.\n- Describe your plan for what to build in pseudocode, written out in great detail.\n- Then output the code replacing the \"\".\n- Ensure that your completion fits within the language context of the provided code snippet.\n\nRules:\n- Only respond with code or comments.\n- Only replace \"\"; do not include any previously written code.\n- Never include \"\" in your response.\n- If the cursor is within a comment, complete the comment meaningfully.\n- Handle ambiguous cases by providing the most contextually appropriate completion.\n- Be consistent with your responses." - }, - { - "role": "user", - "content": "def greet(name):\n print(f\"Hello, {}\")" - }, - { - "role": "assistant", - "content": "name" - }, - { - "role": "user", - "content": "function sum(a, b) {\n return a + ;\n}" - }, - { - "role": "assistant", - "content": "b" - }, - { - "role": "user", - "content": "fn multiply(a: i32, b: i32) -> i32 {\n a * \n}" - }, - { - "role": "assistant", - "content": "b" - }, - { - "role": "user", - "content": "# \ndef add(a, b):\n return a + b" - }, - { - "role": "assistant", - "content": "Adds two numbers" - }, - { - "role": "user", - "content": "# This function checks if a number is even\n" - }, - { - "role": "assistant", - "content": "def is_even(n):\n return n % 2 == 0" - }, - { - "role": "user", - "content": "public class HelloWorld {\n public static void main(String[] args) {\n System.out.println(\"Hello, \");\n }\n}" - }, - { - "role": "assistant", - "content": "world" - }, - { - "role": "user", - "content": "try:\n # Trying to open a file\n file = open(\"example.txt\", \"r\")\n # \nfinally:\n file.close()" - }, - { - "role": "assistant", - "content": "content = file.read()" - }, - { - "role": "user", - "content": "#include \nusing namespace std;\n\nint main() {\n int a = 5, b = 10;\n cout << \"Sum: \" << (a + ) << endl;\n return 0;\n}" - }, - { - "role": "assistant", - "content": "b" - }, - { - "role": "user", - "content": "\n\n\n My Page\n\n\n

Welcome to My Page

\n

This is a sample page with a list of items:

\n
    \n
  • Item 1
  • \n
  • Item 2
  • \n
  • \n
\n\n" - }, - { - "role": "assistant", - "content": "Item 3" - }, - { - "role": "user", - "content": "{CODE}" - } - ] - } - }, + "default": {}, "description": "JSON configuration for LSP-AI generation" } } diff --git a/editors/vscode/src/index.ts b/editors/vscode/src/index.ts index 49d8138..aac57c5 100644 --- a/editors/vscode/src/index.ts +++ b/editors/vscode/src/index.ts @@ -9,6 +9,113 @@ import { let client: LanguageClient; +// We set the default configurations here becauase VS Code tries to combine keys from defaults and user provided values which is annoying to deal with +const defaultServerConfiguration = +{ + "memory": { + "file_store": {} + }, + "models": { + "model1": { + "type": "openai", + "chat_endpoint": "https://api.openai.com/v1/chat/completions", + "model": "gpt-4o", + "auth_token_env_var_name": "OPENAI_API_KEY" + } + } +} + + +const defaultGenerationConfiguration = { + "model": "model1", + "parameters": { + "max_tokens": 128, + "max_context": 1024, + "messages": [ + { + "role": "system", + "content": "Instructions:\n- You are an AI programming assistant.\n- Given a piece of code with the cursor location marked by \"\", replace \"\" with the correct code or comment.\n- First, think step-by-step.\n- Describe your plan for what to build in pseudocode, written out in great detail.\n- Then output the code replacing the \"\".\n- Ensure that your completion fits within the language context of the provided code snippet.\n\nRules:\n- Only respond with code or comments.\n- Only replace \"\"; do not include any previously written code.\n- Never include \"\" in your response.\n- If the cursor is within a comment, complete the comment meaningfully.\n- Handle ambiguous cases by providing the most contextually appropriate completion.\n- Be consistent with your responses." + }, + { + "role": "user", + "content": "def greet(name):\n print(f\"Hello, {}\")" + }, + { + "role": "assistant", + "content": "name" + }, + { + "role": "user", + "content": "function sum(a, b) {\n return a + ;\n}" + }, + { + "role": "assistant", + "content": "b" + }, + { + "role": "user", + "content": "fn multiply(a: i32, b: i32) -> i32 {\n a * \n}" + }, + { + "role": "assistant", + "content": "b" + }, + { + "role": "user", + "content": "# \ndef add(a, b):\n return a + b" + }, + { + "role": "assistant", + "content": "Adds two numbers" + }, + { + "role": "user", + "content": "# This function checks if a number is even\n" + }, + { + "role": "assistant", + "content": "def is_even(n):\n return n % 2 == 0" + }, + { + "role": "user", + "content": "public class HelloWorld {\n public static void main(String[] args) {\n System.out.println(\"Hello, \");\n }\n}" + }, + { + "role": "assistant", + "content": "world" + }, + { + "role": "user", + "content": "try:\n # Trying to open a file\n file = open(\"example.txt\", \"r\")\n # \nfinally:\n file.close()" + }, + { + "role": "assistant", + "content": "content = file.read()" + }, + { + "role": "user", + "content": "#include \nusing namespace std;\n\nint main() {\n int a = 5, b = 10;\n cout << \"Sum: \" << (a + ) << endl;\n return 0;\n}" + }, + { + "role": "assistant", + "content": "b" + }, + { + "role": "user", + "content": "\n\n\n My Page\n\n\n

Welcome to My Page

\n

This is a sample page with a list of items:

\n
    \n
  • Item 1
  • \n
  • Item 2
  • \n
  • \n
\n\n" + }, + { + "role": "assistant", + "content": "Item 3" + }, + { + "role": "user", + "content": "{CODE}" + } + ] + } +} + export function activate(context: vscode.ExtensionContext) { // Configure the server options const serverOptions: ServerOptions = { @@ -16,11 +123,25 @@ export function activate(context: vscode.ExtensionContext) { transport: TransportKind.stdio, }; - // Options to control the language client - const config = vscode.workspace.getConfiguration("lsp-ai"); + // Set the serverConfiguration + let serverConfiguration; + if (Object.keys(vscode.workspace.getConfiguration("lsp-ai").serverConfiguration).length != 0) { + serverConfiguration = vscode.workspace.getConfiguration("lsp-ai").serverConfiguration; + } else { + serverConfiguration = defaultServerConfiguration; + } + + // Set the generationConfiguration + let generationConfiguration; + if (Object.keys(vscode.workspace.getConfiguration("lsp-ai").generationConfiguration).length != 0) { + generationConfiguration = vscode.workspace.getConfiguration("lsp-ai").generationConfiguration; + } else { + generationConfiguration = defaultGenerationConfiguration; + } + const clientOptions: LanguageClientOptions = { documentSelector: [{ scheme: "file" }], - initializationOptions: config.serverConfiguration + initializationOptions: serverConfiguration }; // Create the language client and start the client @@ -37,15 +158,13 @@ export function activate(context: vscode.ExtensionContext) { // Register generate function const generateCommand = 'lsp-ai.generation'; const generateCommandHandler = (editor: vscode.TextEditor) => { - console.log("THE GENERATION CONFIGURATION"); - console.log(config.generationConfiguration); let params = { textDocument: { uri: editor.document.uri.toString(), }, position: editor.selection.active, - model: config.generationConfiguration.model, - parameters: config.generationConfiguration.parameters + model: generationConfiguration.model, + parameters: generationConfiguration.parameters }; client.sendRequest("textDocument/generation", params).then(result => { editor.edit((edit) => { @@ -66,8 +185,8 @@ export function activate(context: vscode.ExtensionContext) { uri: document.uri.toString(), }, position: position, - model: config.generationConfiguration.model, - parameters: config.generationConfiguration.parameters + model: generationConfiguration.model, + parameters: generationConfiguration.parameters }; const result = await client.sendRequest("textDocument/generation", params); return [new vscode.InlineCompletionItem(result["generatedText"])];