diff --git a/vscode-extension/src/extension.ts b/vscode-extension/src/extension.ts index 507da634f..5eececff7 100644 --- a/vscode-extension/src/extension.ts +++ b/vscode-extension/src/extension.ts @@ -59,7 +59,7 @@ export function activate(context: vscode.ExtensionContext) { vscode.commands.registerCommand( COMMANDS.SETUP_ENVIRONMENT_VARIABLES, () => { - vscode.window.showInformationMessage("Will implement next PR"); + setupEnvironmentVariables(context); } ) ); @@ -716,6 +716,86 @@ async function checkPip() { }); } +/** + * Creates an .env file (or opens it if it already exists) to define environment variables + * 1) If .env file exists: + * a) Add helper lines on how to add common API keys (if not currently present) + * 2) If .env file doesn't exist + * b) Add template file containing helper lines from 1a above + */ +async function setupEnvironmentVariables(context: vscode.ExtensionContext) { + // Use home dir because env variables should be global. I get the argument + // for having in the workspace dir. I personally feel this is more + // annoying to setup every time you create a new project when using the + // same API keys, but I can do whatever option you want, not hard to + // implement + const homedir = require("os").homedir(); // This is cross-platform: https://stackoverflow.com/a/9081436 + const defaultEnvPath = path.join(homedir, ".env"); + + const envPath = await vscode.window.showInputBox({ + prompt: "Enter the path of your .env file", + value: defaultEnvPath, + validateInput: (text) => { + if (!text) { + return "File path is required"; + } else if (!text.endsWith(".env")) { + return "File path must end in .env file"; + } + // TODO: Check that file path is a "/.env" file (linux) or "\.env" (Windows) + + // TODO: Check that env path is contained within workspace hierarchy + // (Ex: can't have .env file in a sibling dir otherwise AIConfig + // loadenv can't read it) + return null; + }, + }); + + if (!envPath) { + vscode.window.showInformationMessage( + "Environment variable setup cancelled" + ); + return; + } + + if (fs.existsSync(envPath)) { + vscode.window.showInformationMessage( + "Env file already exists, will implement next PR" + ); + } else { + // Create the .env file from the sample + const envTemplatePath = vscode.Uri.joinPath( + context.extensionUri, + "static", + "env_template.env" + ); + + try { + await vscode.workspace.fs.copy( + envTemplatePath, + vscode.Uri.file(envPath), + { overwrite: false } + ); + } catch (err) { + vscode.window.showErrorMessage( + `Error creating new file ${envTemplatePath}: ${err}` + ); + } + + const doc = await vscode.workspace.openTextDocument(envPath); + if (doc) { + vscode.window.showTextDocument(doc, { + preview: false, + // Tried using vscode.ViewColumn.Active but that overrides existing + // walkthrough window + viewColumn: vscode.ViewColumn.Beside, + }); + vscode.window.showInformationMessage( + "Please define your environment variables." + ); + } + } +} + async function shareAIConfig( context: vscode.ExtensionContext, aiconfigEditorManager: AIConfigEditorManager diff --git a/vscode-extension/static/env_template.env b/vscode-extension/static/env_template.env new file mode 100644 index 000000000..d75aee355 --- /dev/null +++ b/vscode-extension/static/env_template.env @@ -0,0 +1,15 @@ +# Uncomment the following lines to set these common env variables for +# accessing generative AI models. If your model requires other env variables +# you can also set those in this file + +## Used for models from OpenAI such as Chat GPT and Dall-E +## You can get your api key from https://platform.openai.com/api-keys +# OPENAI_API_KEY= + +## Used for models from Google such as Gemini and Gemma +## You can get your api key from https://ai.google.dev/tutorials/setup +# GOOGLE_API_KEY= + +## Used for models hosted on Hugging Face: https://huggingface.co/models +## You can get your token from https://huggingface.co/settings/tokens +# HUGGING_FACE_API_TOKEN=