diff --git a/client/src/copilot/generators/suggestionProvider.ts b/client/src/copilot/generators/suggestionProvider.ts index 2d5a699..04e787f 100644 --- a/client/src/copilot/generators/suggestionProvider.ts +++ b/client/src/copilot/generators/suggestionProvider.ts @@ -2,7 +2,7 @@ import * as vscode from 'vscode'; import { LanguageClient } from 'vscode-languageclient/browser'; import { log } from '../../log'; import { Documents, ModelConfig, PromptConfig } from '../utils/types'; -import { DEFAULT_LLM_MODELS, DEFAULT_LLM_ENDPOINTS } from '../utils/constants'; +import { DEFAULT_LLM_ENDPOINTS } from '../utils/constants'; import { setLLMHealthStatus } from '../healthCheck'; export async function getSuggestion(client: LanguageClient, documents: Documents, promptConfig: PromptConfig): Promise { @@ -10,26 +10,20 @@ export async function getSuggestion(client: LanguageClient, documents: Documents const apiKey = config.get('apiKey'); const provider = config.get('provider'); let llmModel = config.get('llmModel'); - let apiUrl; - if (!llmModel) { - switch (provider) { - case 'gemini': - llmModel = DEFAULT_LLM_MODELS.GEMINI; - apiUrl = DEFAULT_LLM_ENDPOINTS.GEMINI; - break; - case 'openai': - llmModel = DEFAULT_LLM_MODELS.OPENAI; - apiUrl = DEFAULT_LLM_ENDPOINTS.OPENAI; - break; - case 'mistralai': - llmModel = DEFAULT_LLM_MODELS.MISTRALAI; - apiUrl = DEFAULT_LLM_ENDPOINTS.MISTRALAI; - break; - default: - llmModel = ''; - apiUrl = ''; - } + let apiUrl; + switch (provider) { + case 'gemini': + apiUrl = DEFAULT_LLM_ENDPOINTS.GEMINI; + break; + case 'openai': + apiUrl = DEFAULT_LLM_ENDPOINTS.OPENAI; + break; + case 'mistral': + apiUrl = DEFAULT_LLM_ENDPOINTS.MISTRALAI; + break; + default: + apiUrl = ''; } // keys like maxTokens, temperature, topP comes from additionalParams @@ -40,16 +34,9 @@ export async function getSuggestion(client: LanguageClient, documents: Documents llmModel, apiUrl, accessToken: apiKey, - additionalParams: {} + additionalParams: {...additionalParams} }; - if (additionalParams) { - modelConfig.additionalParams = { - ...modelConfig.additionalParams, - ...additionalParams - }; - } - try { log('Generating content...'); const response: string = await client.sendRequest('generateContent', { diff --git a/client/src/copilot/modelGeneratorWizard/modelGeneratorPanel.ts b/client/src/copilot/modelGeneratorWizard/modelGeneratorPanel.ts index f0c2a4a..db81f99 100644 --- a/client/src/copilot/modelGeneratorWizard/modelGeneratorPanel.ts +++ b/client/src/copilot/modelGeneratorWizard/modelGeneratorPanel.ts @@ -40,8 +40,8 @@ export function createFileGeneratorPanel(context: vscode.ExtensionContext, clien }); currentPanel.onDidChangeViewState(e => { - if (currentPanel) { - preloadFileLists(currentPanel, context); + if (currentPanel.visible) { + preloadFileLists(currentPanel); } }); @@ -53,9 +53,11 @@ export function createFileGeneratorPanel(context: vscode.ExtensionContext, clien try { await generateGrammarFile(client, message.filePath); updateGeneratingState('grammar', false); + vscode.window.showInformationMessage('Grammar file generated successfully'); } catch (error) { log(`Error generating grammar file: ${error.message}`); updateGeneratingState('grammar', false, error.message); + vscode.window.showErrorMessage('Error generating grammar file'); } break; case FILE_GENERATORS.GENERATE_MODEL_FILE: @@ -63,9 +65,11 @@ export function createFileGeneratorPanel(context: vscode.ExtensionContext, clien try { await generateModelFile(client, message.packageFile, message.grammarFile); updateGeneratingState('model', false); + vscode.window.showInformationMessage('Model file generated successfully'); } catch (error) { log(`Error generating model file: ${error.message}`); updateGeneratingState('model', false, error.message); + vscode.window.showErrorMessage('Error generating model file'); } break; case FILE_GENERATORS.REQUEST_FILE_LIST: @@ -80,7 +84,7 @@ export function createFileGeneratorPanel(context: vscode.ExtensionContext, clien currentPanel.webview.html = getWebviewContent(currentPanel.webview, context.extensionUri); } -async function preloadFileLists(panel: vscode.WebviewPanel, context: vscode.ExtensionContext) { +async function preloadFileLists(panel: vscode.WebviewPanel) { const mdFiles = await getFileList('md'); const jsonFiles = await getFileList('json'); diff --git a/client/src/copilot/quickPick.ts b/client/src/copilot/quickPick.ts index d3f6270..51723aa 100644 --- a/client/src/copilot/quickPick.ts +++ b/client/src/copilot/quickPick.ts @@ -18,6 +18,7 @@ export function registerQuickPickCommand(context: vscode.ExtensionContext, clien { label: GENERAL.QUICK_PICK_OPTION_SETTINGS }, { label: GENERAL.QUICK_PICK_OPTION_SUGGESTIONS }, { label: GENERAL.QUICK_PICK_OPTION_CHAT_AGENT }, + { label: GENERAL.QUICK_PICK_OPTION_GENERATOR }, { label: '', kind: vscode.QuickPickItemKind.Separator }, { label: enableInlineSuggestions ? GENERAL.QUICK_PICK_OPTION_DISABLE_INLINE_SUGGESTIONS : GENERAL.QUICK_PICK_OPTION_ENABLE_INLINE_SUGGESTIONS }, { label: enableCodeActions ? GENERAL.QUICK_PICK_OPTION_DISABLE_CODE_ACTIONS : GENERAL.QUICK_PICK_OPTION_ENABLE_CODE_ACTIONS } @@ -28,8 +29,10 @@ export function registerQuickPickCommand(context: vscode.ExtensionContext, clien vscode.commands.executeCommand('cicero-vscode-extension.configureSettings'); } else if (selection?.label === GENERAL.QUICK_PICK_OPTION_SUGGESTIONS) { vscode.commands.executeCommand('cicero-vscode-extension.startPromptProviderUI'); - } else if (selection?.label === 'Open Chat Agent') { + } else if (selection?.label === GENERAL.QUICK_PICK_OPTION_CHAT_AGENT) { createOrShowChatPanel(client, context); + } else if (selection?.label === GENERAL.QUICK_PICK_OPTION_GENERATOR) { + vscode.commands.executeCommand('cicero-vscode-extension.openFileGenerator'); } else if (selection?.label === GENERAL.QUICK_PICK_OPTION_ENABLE_INLINE_SUGGESTIONS || selection?.label === GENERAL.QUICK_PICK_OPTION_DISABLE_INLINE_SUGGESTIONS) { vscode.commands.executeCommand('cicero-vscode-extension.toggleInlineSuggestions'); } else if (selection?.label === GENERAL.QUICK_PICK_OPTION_ENABLE_CODE_ACTIONS || selection?.label === GENERAL.QUICK_PICK_OPTION_DISABLE_CODE_ACTIONS) { diff --git a/client/src/copilot/settingsView/configSetting.ts b/client/src/copilot/settingsView/configSetting.ts index a969146..db4034d 100644 --- a/client/src/copilot/settingsView/configSetting.ts +++ b/client/src/copilot/settingsView/configSetting.ts @@ -1,9 +1,10 @@ import * as vscode from 'vscode'; -import { ASSETS, CONFIG_DEFAULTS } from '../utils/constants'; +import { ASSETS, CONFIG_DEFAULTS, COPILOT_SETTINGS } from '../utils/constants'; import { htmlTemplate } from './templates/settingsView'; import { cssTemplate } from './templates/settingsStyle'; import { scriptTemplate } from './templates/settingScript'; import { checkCopilotHealth, copilotHealthStatus } from '../healthCheck'; +import { log } from '../../log'; export function createSettingsWebview(context: vscode.ExtensionContext, client: any) { const column = vscode.ViewColumn.Beside; @@ -25,35 +26,60 @@ export function createSettingsWebview(context: vscode.ExtensionContext, client: panel.iconPath = iconPath; const config = vscode.workspace.getConfiguration('cicero-vscode-extension'); - const configValues = { - apiKey: config.get('apiKey', CONFIG_DEFAULTS.apiKey), - apiUrl: config.get('apiUrl', CONFIG_DEFAULTS.apiUrl), - provider: config.get('provider', CONFIG_DEFAULTS.provider), - llmModel: config.get('llmModel', CONFIG_DEFAULTS.llmModel), - additionalParams: JSON.stringify(config.get('additionalParams', CONFIG_DEFAULTS.additionalParams), null, 2) - }; - - panel.webview.html = htmlTemplate(cssTemplate, scriptTemplate, configValues); panel.webview.onDidReceiveMessage(async message => { switch (message.command) { case 'saveSettings': const target = message.scope === 'workspace' ? vscode.ConfigurationTarget.Workspace : vscode.ConfigurationTarget.Global; + + if (message.scope === 'workspace' && !vscode.workspace.workspaceFolders) { + vscode.window.showErrorMessage(COPILOT_SETTINGS.CONNECTION_FAILED); + panel.webview.postMessage({ command: 'showError', message: COPILOT_SETTINGS.WORKSPACE_REQUIRED }); + return; + } + + const sanitizedLLMModel = message.llmModel.trim(); + await config.update('apiKey', message.apiKey, target); await config.update('provider', message.provider, target); - await config.update('llmModel', message.llmModel, target); + await config.update('llmModel', sanitizedLLMModel, target); await config.update('additionalParams', JSON.parse(message.additionalParams), target); - vscode.window.showInformationMessage('Configuration updated successfully!'); + vscode.window.showInformationMessage(COPILOT_SETTINGS.CONFIG_UPDATED_SUCCESS); await checkCopilotHealth(client) - if (copilotHealthStatus === true) - vscode.window.showInformationMessage('Connection to Copilot established successfully!'); - else - vscode.window.showErrorMessage('Connection to Copilot failed!'); + log('Copilot settings updated'+copilotHealthStatus); + if (copilotHealthStatus === true){ + vscode.window.showInformationMessage(COPILOT_SETTINGS.CONNECTION_SUCCESS); + panel.webview.postMessage({ command: 'hideError' }); + } + else { + vscode.window.showErrorMessage(COPILOT_SETTINGS.CONNECTION_FAILED); + panel.webview.postMessage({ command: 'showError', message: COPILOT_SETTINGS.CONNECTION_FAILED_MESSAGE }); + } break; } }); + + panel.onDidChangeViewState(() => { + if (panel.visible) { + let config = vscode.workspace.getConfiguration('cicero-vscode-extension'); + const updatedConfigValues = { + apiKey: config.get('apiKey', CONFIG_DEFAULTS.apiKey), + apiUrl: config.get('apiUrl', CONFIG_DEFAULTS.apiUrl), + provider: config.get('provider', CONFIG_DEFAULTS.provider), + llmModel: config.get('llmModel', CONFIG_DEFAULTS.llmModel), + additionalParams: JSON.stringify(config.get('additionalParams', CONFIG_DEFAULTS.additionalParams), null, 2) + }; + panel.webview.html = htmlTemplate(cssTemplate, scriptTemplate, updatedConfigValues); + } + }); + + panel.onDidDispose(() => { + panel.dispose(); + }); + + panel.options } diff --git a/client/src/copilot/settingsView/templates/settingScript.ts b/client/src/copilot/settingsView/templates/settingScript.ts index 1e8a4a6..38623b5 100644 --- a/client/src/copilot/settingsView/templates/settingScript.ts +++ b/client/src/copilot/settingsView/templates/settingScript.ts @@ -53,4 +53,37 @@ export const scriptTemplate = ` } } + function updateLLMModel() { + const provider = document.getElementById('provider').value; + const llmModelInput = document.getElementById('llmModel'); + let defaultModel = ''; + + switch (provider) { + case 'gemini': + defaultModel = 'gemini-pro'; + break; + case 'openai': + defaultModel = 'gpt-3.5-turbo'; + break; + case 'mistral': + defaultModel = 'mistral-large-latest'; + break; + } + + llmModelInput.value = defaultModel; + } + + window.addEventListener('message', event => { + const message = event.data; + const errorElement = document.getElementById('copilotHealthError'); + switch (message.command) { + case 'showError': + errorElement.innerText = message.message; + errorElement.style.display = 'block'; + break; + case 'hideError': + errorElement.style.display = 'none'; + break; + } + }); `; diff --git a/client/src/copilot/settingsView/templates/settingsStyle.ts b/client/src/copilot/settingsView/templates/settingsStyle.ts index 1e79a0f..23033ba 100644 --- a/client/src/copilot/settingsView/templates/settingsStyle.ts +++ b/client/src/copilot/settingsView/templates/settingsStyle.ts @@ -117,7 +117,7 @@ export const cssTemplate = ` color: var(--input-foreground); } .error-message { /* New class for error messages */ - color: var(--error-foreground); + color: var(--vscode-list-errorForeground); margin-top: 5px; font-size: 0.9em; display: none; /* Hidden by default */ diff --git a/client/src/copilot/settingsView/templates/settingsView.ts b/client/src/copilot/settingsView/templates/settingsView.ts index 8a98829..c9ac9c8 100644 --- a/client/src/copilot/settingsView/templates/settingsView.ts +++ b/client/src/copilot/settingsView/templates/settingsView.ts @@ -29,7 +29,7 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:

Select the AI provider.

- @@ -39,7 +39,7 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:
- +

The specific language model (default: Gemini - gemini-pro, OpenAI - gpt-3.5-turbo, MistralAI - mistral-large-latest).

@@ -54,13 +54,14 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:

Select whether to save the settings globally (for all projects) or for the current workspace only.

+