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

Feat/ai/explain #568

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
1 change: 1 addition & 0 deletions src/snyk/common/constants/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export const SNYK_WORKSPACE_SCAN_COMMAND = 'snyk.workspace.scan';
export const SNYK_TRUST_WORKSPACE_FOLDERS_COMMAND = 'snyk.trustWorkspaceFolders';
export const SNYK_GET_ACTIVE_USER = 'snyk.getActiveUser';
export const SNYK_CODE_FIX_DIFFS_COMMAND = 'snyk.code.fixDiffs';
export const SNYK_CODE_GENERATE_AI_EXPLANATION = 'snyk.generateAIExplanation';
export const SNYK_CODE_SUBMIT_FIX_FEEDBACK = 'snyk.code.submitFixFeedback';
export const SNYK_FEATURE_FLAG_COMMAND = 'snyk.getFeatureFlagStatus';
export const SNYK_CLEAR_CACHE_COMMAND = 'snyk.clearCache';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
SNYK_IGNORE_ISSUE_COMMAND,
SNYK_OPEN_BROWSER_COMMAND,
SNYK_OPEN_LOCAL_COMMAND,
SNYK_CODE_GENERATE_AI_EXPLANATION

Check failure on line 13 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Insert `,`

Check failure on line 13 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Insert `,`
} from '../../../common/constants/commands';
import { SNYK_VIEW_SUGGESTION_CODE } from '../../../common/constants/views';
import { ErrorHandler } from '../../../common/error/errorHandler';
Expand Down Expand Up @@ -304,6 +305,79 @@
}
break;
}
case 'generateVulnerabilityExplanation': {
this.logger.info('case generateVulnerabilityExplanation');
console.log("case generateVulnerabilityExplanation");

Check failure on line 310 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `"case·generateVulnerabilityExplanation"` with `'case·generateVulnerabilityExplanation'`

Check failure on line 310 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `"case·generateVulnerabilityExplanation"` with `'case·generateVulnerabilityExplanation'`
const { suggestion } = message.args;
const filePath = suggestion.filePath;
const folderPath = this.getWorkspaceFolderPath(filePath);
const relativePath = relative(folderPath, filePath);

Check warning on line 314 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

'relativePath' is assigned a value but never used. Allowed unused vars must match /^_/u

Check warning on line 314 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

'relativePath' is assigned a value but never used. Allowed unused vars must match /^_/u

const issueId = suggestion.id;

const fileContent = readFileSync(filePath, 'utf8');

const ruleKey = suggestion.rule;
const ruleMessage = suggestion.message;

let derivationLineNumbers: Set<number> = new Set<number>();
for (const markerLocation of suggestion.markers!) {
for (const markerPos of markerLocation.pos) {
const lines = markerPos.rows;
for (const line of lines) {
derivationLineNumbers.add(line + 1);
}
}
markerLocation.pos

Check failure on line 331 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Insert `;`

Check failure on line 331 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Insert `;`
}
console.log("derivation lines: ", ...derivationLineNumbers);

Check failure on line 333 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `"derivation·lines:·"` with `'derivation·lines:·'`

Check failure on line 333 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `"derivation·lines:·"` with `'derivation·lines:·'`

let derivationLines: string[] = [];
let fileLines: string[] = fileContent.split("\n");

Check failure on line 336 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `"\n"` with `'\n'`

Check failure on line 336 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `"\n"` with `'\n'`
for (const derivationLineNumber of derivationLineNumbers) {
derivationLines.push(fileLines.at(derivationLineNumber - 1)!);
}
let derivation = derivationLines.join(",");

Check failure on line 340 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `","` with `','`

Check failure on line 340 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `","` with `','`
derivation = derivation.replace(/\t/g, " ");

Check failure on line 341 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `"··"` with `'··'`

Check failure on line 341 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `"··"` with `'··'`
console.log("derivation: ", derivation);

Check failure on line 342 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `"derivation:·"` with `'derivation:·'`

Check failure on line 342 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `"derivation:·"` with `'derivation:·'`

var explanation: string = ""

Check failure on line 344 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Unexpected var, use let or const instead

Check failure on line 344 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (ubuntu-latest)

Replace `""` with `'';`

Check failure on line 344 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Unexpected var, use let or const instead

Check failure on line 344 in src/snyk/snykCode/views/suggestion/codeSuggestionWebviewProvider.ts

View workflow job for this annotation

GitHub Actions / Build and Test (macos-latest)

Replace `""` with `'';`
explanation = await vscode.commands.executeCommand(
SNYK_CODE_GENERATE_AI_EXPLANATION,
derivation,
ruleKey,
ruleMessage,
);
console.log("got vulnerability explanation: ", explanation);

void this.postSuggestMessage({ type: 'setVulnerabilityExplanation', args: { explanation: explanation } });

break;
}
case 'generateFixExplanation': {
this.logger.info('case generateFixExplanation');
console.log("case generateFixExplanation");
const { suggestion } = message.args;
const filePath = suggestion.filePath;
const folderPath = this.getWorkspaceFolderPath(filePath);
const relativePath = relative(folderPath, filePath);

const issueId = suggestion.id;

const fileContent = readFileSync(filePath, 'utf8');

// const ruleKey = suggestion.rule;
// const ruleMessage = suggestion.message;
var explanation: string = ""
explanation = await vscode.commands.executeCommand(
SNYK_CODE_GENERATE_AI_EXPLANATION,
folderPath,
relativePath,
issueId,
);
console.log("got fix explanation: ", explanation);
break;
}

default: {
throw new Error('Unknown message type');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,34 @@ declare const acquireVsCodeApi: any;
};
};

type GenerateFixExplanationMessage = {
type: 'generateFixExplanation';
args: {
suggestion: Suggestion;
};
};

type GenerateVulnerabilityExplanationMessage = {
type: 'generateVulnerabilityExplanation';
args: {
suggestion: Suggestion;
};
};

type SetFixExplanationMessage = {
type: 'setFixExplanation';
args: {
explanation: string;
};
};

type SetVulnerabilityExplanationMessage = {
type: 'setVulnerabilityExplanation';
args: {
explanation: string;
};
};

type ApplyGitDiffMessage = {
type: 'applyGitDiff';
args: {
Expand Down Expand Up @@ -113,6 +141,10 @@ declare const acquireVsCodeApi: any;
| SetSuggestionMessage
| GetSuggestionMessage
| GetAutofixDiffsMesssage
| GenerateFixExplanationMessage
| GenerateVulnerabilityExplanationMessage
| SetVulnerabilityExplanationMessage
| SetFixExplanationMessage
| ApplyGitDiffMessage
| SetAutofixDiffsMessage
| SetAutofixErrorMessage;
Expand Down Expand Up @@ -213,12 +245,40 @@ declare const acquireVsCodeApi: any;
const retryGenerateFixButton = document.getElementById('retry-generate-fix') as HTMLElement;
const generateAIFixButton = document.getElementById('generate-ai-fix') as HTMLElement;

// AI Explain buttons
const generateVulnerabilityExplanationButton = document.getElementById('generate-vulnerability-explanation-button') as HTMLButtonElement;
const generateFixExplanationButton = document.getElementById('generate-fix-explanation-button') as HTMLButtonElement;

const ignoreContainerElements = document.getElementsByClassName('ignore-action-container');
if (ignoreContainerElements) {
toggleElement(ignoreContainerElements[0] as HTMLElement, 'show');
(ignoreContainerElements[0] as HTMLElement).style.display = suggestion?.showInlineIgnoresButton ? 'block' : 'none';
}

function generateVulnerabilityExplanation() {
console.log("inside generateVulnerabilityExplanation callback");
if (!suggestion) {
return;
}
const message: GenerateVulnerabilityExplanationMessage = {
type: 'generateVulnerabilityExplanation',
args: { suggestion },
};
sendMessage(message);
}

function generateFixExplanation() {
console.log("inside generateFixExplanation callback");
if (!suggestion) {
return;
}
const message: GenerateFixExplanationMessage = {
type: 'generateFixExplanation',
args: { suggestion },
};
sendMessage(message);
}

function generateAIFix() {
if (!suggestion) {
return;
Expand Down Expand Up @@ -261,6 +321,16 @@ declare const acquireVsCodeApi: any;
retryGenerateFixButton?.addEventListener('click', retryGenerateAIFix);
applyFixButton?.addEventListener('click', applyFix);

// AI Explain elements
generateVulnerabilityExplanationButton?.addEventListener('click', generateVulnerabilityExplanation);
generateFixExplanationButton?.addEventListener('click', generateFixExplanation);

// generateVulnerabilityExplanationButton: document.getElementById('generate-vulnerability-explanation-button') as HTMLElement;
// vulnerabilityExplainationTextSection: document.getElementById('info-vulnerability-explanation') as HTMLElement;
// vulnerabilityExplainationText: document.getElementById("vulnerability-explanation-text") as HTMLElement;

// generateVulnerabilityExplanationButton?.addEventListener('click', generateAIExplanation);

// different AI fix states
const fixLoadingIndicatorElem = document.getElementById('fix-loading-indicator') as HTMLElement;
const fixWrapperElem = document.getElementById('fix-wrapper') as HTMLElement;
Expand Down Expand Up @@ -303,6 +373,7 @@ declare const acquireVsCodeApi: any;
toggleElement(diffTopElem, 'hide');
toggleElement(diffElem, 'hide');
toggleElement(applyFixButton, 'hide');
// toggleElement(generateAIExplanationButton, 'hide');
return;
}

Expand All @@ -312,6 +383,7 @@ declare const acquireVsCodeApi: any;
toggleElement(diffTopElem, 'show');
toggleElement(diffElem, 'show');
toggleElement(applyFixButton, 'show');
// toggleElement(generateAIExplanationButton, 'show');

diffNumElem.innerText = suggestion.diffs.length.toString();
diffNum2Elem.innerText = suggestion.diffs.length.toString();
Expand Down Expand Up @@ -413,6 +485,18 @@ declare const acquireVsCodeApi: any;
toggleElement(fixWrapperElem, 'hide');
toggleElement(fixErrorSectionElem, 'show');
}
case 'setVulnerabilityExplanation': {
console.log("IN SET EXPLAIN CASE");
// const { explainText } = elements;
// explainText.innerText = JSON.parse(message.args.suggestion)["explanation"]
break;
}
case 'setFixExplanation': {
console.log("IN SET EXPLAIN CASE");
// const { explainText } = elements;
// explainText.innerText = JSON.parse(message.args.suggestion)["explanation"]
break;
}
}
});
})();
32 changes: 32 additions & 0 deletions src/snyk/snykCode/views/suggestion/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,20 @@ export type GetAutofixDiffsMesssage = {
};
};

export type GenerateFixExplanationMessage = {
type: 'generateFixExplanation';
args: {
suggestion: Suggestion;
};
};

export type GenerateVulnerabilityExplanationMessage = {
type: 'generateVulnerabilityExplanation';
args: {
suggestion: Suggestion;
};
};

export type ApplyGitDiffMessage = {
type: 'applyGitDiff';
args: {
Expand Down Expand Up @@ -101,11 +115,29 @@ export type SetAutofixErrorMessage = {
};
};

export type SetVulnerabilityExplanation = {
type: 'setVulnerabilityExplanation';
args: {
explanation: string;
};
};

export type SetFixExplanation = {
type: 'setFixExplanation';
args: {
explanation: string;
};
};

export type SuggestionMessage =
| OpenLocalMessage
| OpenBrowserMessage
| IgnoreIssueMessage
| GetAutofixDiffsMesssage
| GenerateVulnerabilityExplanationMessage
| GenerateFixExplanationMessage
| SetVulnerabilityExplanation
| SetFixExplanation
| ApplyGitDiffMessage
| SetSuggestionMessage
| GetSuggestionMessage
Expand Down
Loading