Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for issues identified during bug bash and Release Notes #60

Open
wants to merge 22 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
5a0b689
Changes to clear generated temp file
kshitij79 Aug 16, 2024
ceec524
Fix: remove empty chat view definition
kshitij79 Aug 18, 2024
ce420f6
feat: Move File Generator to Command Palette
kshitij79 Aug 18, 2024
664ab50
feat: Auto populate llm model in config settings
kshitij79 Aug 20, 2024
020ed61
Fixed context caching and Improved LLM prompt handling, and response …
kshitij79 Aug 21, 2024
c60ccfa
Fix typos in Mistral endpoint and improve user feedback during file g…
kshitij79 Aug 21, 2024
111ceda
Minor changes in inline suggestions prompt
kshitij79 Aug 24, 2024
f2f79b8
Refined diagnostics reporting
kshitij79 Aug 25, 2024
7290718
Updated README and CHANGELOG for v2.0.0 release
kshitij79 Aug 25, 2024
8bb6873
fix: Prevent saving workspace settings when no workspace is open
kshitij79 Aug 25, 2024
ab4b1a6
Merge branch 'kshitij79/I45/Fixed-Config-Settings' into kshitij79/Bug…
kshitij79 Aug 25, 2024
594aa84
Merge branch 'kshitij79/I47/Context-Caching' into kshitij79/BugBash/A…
kshitij79 Aug 25, 2024
b04c4d1
Merge branch 'kshitij79/I49/Generator-Command-Palette' into kshitij79…
kshitij79 Aug 25, 2024
c601931
Merge branch 'kshitij79/I51/Clear-Temp-File' into kshitij79/BugBash/A…
kshitij79 Aug 25, 2024
245410a
Merge branch 'kshitij79/I52/Improved-Diagnostics' into kshitij79/BugB…
kshitij79 Aug 25, 2024
f61e4ca
Merge branch 'kshitij79/Release-2.0.0/Documentation' into kshitij79/B…
kshitij79 Aug 25, 2024
1cd74c1
fix: wrong label for chat panel
kshitij79 Aug 26, 2024
940a206
Merge branch 'kshitij79/I49/Generator-Command-Palette' into kshitij79…
kshitij79 Aug 26, 2024
38ea32e
Resolved merge conflict in package json
kshitij79 Aug 31, 2024
962914d
Resolved merge conflict
kshitij79 Aug 31, 2024
d84b38b
Resolved merge conflict
kshitij79 Aug 31, 2024
5bb4398
Merge branch 'kshitij79/I44/empty-chat-window' into kshitij79/BugBash…
kshitij79 Aug 31, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
## Change Log

## 2.0.0
- Inline Suggestions: Real-time, context-aware code completions for TypeScript, Concerto, and more.
- Prompt Provider UI: Context-aware prompts based on user input and surrounding code context.
- Status Bar Item: Quick access to actions and status updates for AI model connections.
- Configuration Settings UI: Seamless AI model configuration and API key integration.
- Chat Panel: Interactive chat for code analysis, debugging, and Q&A with AI models.
- Grammar/Model Generation Wizard: Automates grammar and data model creation from markdown files.

### 0.22.0
- Update to Cicero 0.22.0
### 0.21.17
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,9 @@ This is a [Web Extension](https://code.visualstudio.com/api/extension-guides/web
- Compilation of Concerto files to other languages
- Syntax highlighting for all files
- Compilation and problem markers
- AI-powered context-aware inline code suggestions
- Chat Panel for AI-driven Q&A sessions and debugging support
- Grammar/Model generation from markdown files

### Commands

Expand All @@ -44,6 +47,10 @@ This is a [Web Extension](https://code.visualstudio.com/api/extension-guides/web
![Code Gen GIF](./assets/Code%20Gen.gif)

- Work offline by downloading Concerto model dependencies (context-click on a `*.cto` file)
- Configure copilot settings
- Access AI-powered suggestions and chat with the Co-Pilot for real-time assistance
- Generate grammar and data models from markdown files
- Toggle inline suggestions and code actions

### Concerto Snippets

Expand Down
43 changes: 15 additions & 28 deletions client/src/copilot/generators/suggestionProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,28 @@ 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<string | null> {
const config = vscode.workspace.getConfiguration('cicero-vscode-extension');
const apiKey = config.get<string>('apiKey');
const provider = config.get<string>('provider');
let llmModel = config.get<string>('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
Expand All @@ -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', {
Expand Down
10 changes: 7 additions & 3 deletions client/src/copilot/modelGeneratorWizard/modelGeneratorPanel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ export function createFileGeneratorPanel(context: vscode.ExtensionContext, clien
});

currentPanel.onDidChangeViewState(e => {
if (currentPanel) {
preloadFileLists(currentPanel, context);
if (currentPanel.visible) {
preloadFileLists(currentPanel);
}
});

Expand All @@ -53,19 +53,23 @@ 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:
updateGeneratingState('model', true);
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:
Expand All @@ -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');

Expand Down
5 changes: 4 additions & 1 deletion client/src/copilot/quickPick.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand All @@ -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) {
Expand Down
58 changes: 42 additions & 16 deletions client/src/copilot/settingsView/configSetting.ts
Original file line number Diff line number Diff line change
@@ -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;
Expand All @@ -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<string>('apiKey', CONFIG_DEFAULTS.apiKey),
apiUrl: config.get<string>('apiUrl', CONFIG_DEFAULTS.apiUrl),
provider: config.get<string>('provider', CONFIG_DEFAULTS.provider),
llmModel: config.get<string>('llmModel', CONFIG_DEFAULTS.llmModel),
additionalParams: JSON.stringify(config.get<object>('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<string>('apiKey', CONFIG_DEFAULTS.apiKey),
apiUrl: config.get<string>('apiUrl', CONFIG_DEFAULTS.apiUrl),
provider: config.get<string>('provider', CONFIG_DEFAULTS.provider),
llmModel: config.get<string>('llmModel', CONFIG_DEFAULTS.llmModel),
additionalParams: JSON.stringify(config.get<object>('additionalParams', CONFIG_DEFAULTS.additionalParams), null, 2)
};
panel.webview.html = htmlTemplate(cssTemplate, scriptTemplate, updatedConfigValues);
}
});

panel.onDidDispose(() => {
panel.dispose();
});

panel.options
}

33 changes: 33 additions & 0 deletions client/src/copilot/settingsView/templates/settingScript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
});
`;
2 changes: 1 addition & 1 deletion client/src/copilot/settingsView/templates/settingsStyle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
Expand Down
9 changes: 5 additions & 4 deletions client/src/copilot/settingsView/templates/settingsView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:
<label for="provider">Provider <span class="required-asterisk">*</span></label>
<p>Select the AI provider.</p>
<div class="select-container">
<select id="provider" style="width: 100%;">
<select id="provider" style="width: 100%;" onchange="updateLLMModel()">
<option value="gemini" ${configValues.provider === 'gemini' ? 'selected' : ''}>Gemini</option>
<option value="openai" ${configValues.provider === 'openai' ? 'selected' : ''}>OpenAI</option>
<option value="mistral" ${configValues.provider === 'mistral' ? 'selected' : ''}>MistralAI</option>
Expand All @@ -39,7 +39,7 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:
<span class="error-message" id="providerError"></span>
</div>
<div class="form-group">
<label for="llmModel">LLM Model</label>
<label for="llmModel">LLM Model <span class="required-asterisk">*</span></label>
<p>The specific language model (default: Gemini - gemini-pro, OpenAI - gpt-3.5-turbo, MistralAI - mistral-large-latest).</p>
<input type="text" id="llmModel" value="${configValues.llmModel}">
<span class="error-message" id="llmModelError"></span>
Expand All @@ -54,13 +54,14 @@ export const htmlTemplate = (css: string, script: string, configValues: { [key:
<p>Select whether to save the settings globally (for all projects) or for the current workspace only.</p>
<div class="select-container">
<select id="scope" style="width: 100%;">
<option value="workspace" selected>Workspace</option>
<option value="global">Global</option>
<option value="workspace">Workspace</option>
<option value="global" selected>Global</option>
</select>
<i class="codicon codicon-chevron-down"></i>
</div>
</div>
<button class="button" onclick="saveSettings()">Save Settings</button>
<span class="error-message" id="copilotHealthError"></span>
</div>
<script>
${script}
Expand Down
14 changes: 11 additions & 3 deletions client/src/copilot/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ export const GENERAL = {
QUICK_PICK_STATUS_OK: '$(copilot) Status: Ready',
QUICK_PICK_STATUS_ERROR: '$(copilot) Status: Configuration Error',
QUICK_PICK_PLACEHOLDER: 'Choose an action',
QUICK_PICK_OPTION_CHAT_AGENT: 'Open Chat Agent',
QUICK_PICK_OPTION_CHAT_AGENT: '$(comment-discussion) Open Chat Agent',
QUICK_PICK_OPTION_GENERATOR: '$(wand) Model Generation Wizard',
QUICK_PICK_OPTION_SETTINGS: '$(gear) Open Copilot Settings',
QUICK_PICK_OPTION_SUGGESTIONS: '$(copilot) Get Inline Suggestions',
QUICK_PICK_OPTION_ENABLE_INLINE_SUGGESTIONS: 'Enable Inline Suggestions',
Expand Down Expand Up @@ -87,7 +88,7 @@ export const DEFAULT_LLM_MODELS = {
export const DEFAULT_LLM_ENDPOINTS = {
GEMINI: 'https://generativelanguage.googleapis.com/v1beta/models/gemini-pro:generateContent',
OPENAI: 'https://api.openai.com/v1/chat/completions',
MISTRALAI: 'https://api.mistralai.com/v1/chat/completions'
MISTRALAI: 'https://api.mistral.ai/v1/chat/completions'
};

// Constants for Panel Manager
Expand Down Expand Up @@ -120,4 +121,11 @@ export const ASSETS = {
ACCORD_LOGO_DARK: 'assets/dark/accord_logo.png',
ACCORD_LOGO_LIGHT: 'assets/light/accord_logo.png'
};


export const COPILOT_SETTINGS = {
CONFIG_UPDATED_SUCCESS: 'Configuration updated successfully!',
CONNECTION_SUCCESS: 'Connection to Copilot established successfully!',
CONNECTION_FAILED: 'Connection to Copilot failed!',
CONNECTION_FAILED_MESSAGE: 'Connection to Copilot failed! Please check your API key, billing status, and LLM model.',
WORKSPACE_REQUIRED: 'Cannot save settings with "Workspace" scope because no workspace is open. Please save them as Global settings.'
};
Loading
Loading