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: code smell command, display commands error in chat #602

Merged
merged 40 commits into from
Aug 11, 2023
Merged
Show file tree
Hide file tree
Changes from 33 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
02cd6b9
add tab-to-complete
abeatrix Aug 8, 2023
4eacb3d
replace selection with SelectionOrEntireFile
abeatrix Aug 8, 2023
7b2633b
add interaction with error message on error
abeatrix Aug 8, 2023
523f86c
add preventDefault
abeatrix Aug 8, 2023
bcacfd3
add commands to walkthrough and update old ones
abeatrix Aug 8, 2023
b287c13
revert chat
abeatrix Aug 8, 2023
45100e8
add getActiveTextEditorSelectionOrVisibleContent
abeatrix Aug 8, 2023
16414a8
add getActiveTextEditorSelectionOrVisibleContent
abeatrix Aug 8, 2023
1191ff1
Add annoucement
abeatrix Aug 8, 2023
add8162
update Explain Code and custom prompt
abeatrix Aug 8, 2023
2f4eb8c
Merge branch 'main' into bee/commands-update
abeatrix Aug 8, 2023
28c9698
update error style, add telemetryService
abeatrix Aug 9, 2023
68964b5
feat: add code smell detection
abeatrix Aug 9, 2023
4a8cd77
enhance custom prompt creation, add slashCommand
abeatrix Aug 9, 2023
9091da5
navigation of command suggestions w/ arrow keys
abeatrix Aug 9, 2023
97b0a55
show error on non-existing / command, add logs
abeatrix Aug 9, 2023
b7f76a5
display file path w/ link & selection range
abeatrix Aug 9, 2023
ed19604
clean up CustomPrompt recipe
abeatrix Aug 9, 2023
66a1e32
fix file range formatting in prompts
abeatrix Aug 9, 2023
10a4b67
fix test
abeatrix Aug 9, 2023
dd38fbf
simplify promise handling in menus
abeatrix Aug 9, 2023
14be3bb
update error text
abeatrix Aug 9, 2023
15a5d25
update changelog
abeatrix Aug 9, 2023
1063253
Merge branch 'main' into bee/commands-update
abeatrix Aug 9, 2023
2f3681b
remove editorSelectionOrVisibleContent from agent
abeatrix Aug 10, 2023
0007f18
Merge branch 'bee/commands-update' of https://github.com/sourcegraph/…
abeatrix Aug 10, 2023
fab0c12
Apply suggestions from code review
abeatrix Aug 10, 2023
d42c501
Remove toJSON() and use path lib
abeatrix Aug 10, 2023
49edcd0
Merge branch 'main' into bee/commands-update
abeatrix Aug 10, 2023
90a923d
fix conflicts
abeatrix Aug 10, 2023
bf20c22
update smell code prompt, add util, use XML tags
abeatrix Aug 10, 2023
a0dd969
fix command names and inline chat selection
abeatrix Aug 10, 2023
eda1e2d
remove selection requirement for code smell
abeatrix Aug 10, 2023
c2160fc
Update lib/shared/src/chat/recipes/custom-prompt.ts
abeatrix Aug 10, 2023
2d2b3a1
Update lib/shared/src/chat/recipes/custom-prompt.ts
abeatrix Aug 10, 2023
ba6a9a6
refactor: simplify interaction and context utilities
abeatrix Aug 10, 2023
82f5b45
show error for command when no file is opened
abeatrix Aug 11, 2023
33b5aa5
update error message
abeatrix Aug 11, 2023
543aaad
fix: use InlineController for active selection
abeatrix Aug 11, 2023
f620408
update editor classes
abeatrix Aug 11, 2023
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
4 changes: 4 additions & 0 deletions agent/src/editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,10 @@ export class AgentEditor implements Editor {
return this.getActiveTextEditorSelection()
}

public getActiveTextEditorSelectionOrVisibleContent(): ActiveTextEditorSelection | null {
throw new Error('Method not implemented.')
}

public getActiveTextEditorDiagnosticsForRange(): ActiveTextEditorDiagnostic[] | null {
throw new Error('Method not implemented.')
}
Expand Down
9 changes: 6 additions & 3 deletions lib/shared/src/chat/prompts/default-prompts.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,9 @@
},
"Explain Code": {
"slashCommand": "explain",
"prompt": "Explain what the selected code does in simple terms. Assume the audience is a beginner programmer who has just learned the language features and basic syntax. Focus on explaining: 1) The purpose of the code 2) What input(s) it takes 3) What output(s) it produces 4) How it achieves its purpose through the logic and algorithm. 5) Any important logic flows or data transformations happening. Use simple language a beginner could understand. Include enough detail to give a full picture of what the code aims to accomplish without getting too technical. Format the explanation in coherent paragraphs, using proper punctuation and grammar. Write the explanation assuming no prior context about the code is known. Do not make assumptions about variables or functions not shown in the shared code.",
"prompt": "Explain what the selected code does in simple terms. Assume the audience is a beginner programmer who has just learned the language features and basic syntax. Focus on explaining: 1) The purpose of the code 2) What input(s) it takes 3) What output(s) it produces 4) How it achieves its purpose through the logic and algorithm. 5) Any important logic flows or data transformations happening. Use simple language a beginner could understand. Include enough detail to give a full picture of what the code aims to accomplish without getting too technical. Format the explanation in coherent paragraphs, using proper punctuation and grammar. Write the explanation assuming no prior context about the code is known. Do not make assumptions about variables or functions not shown in the shared code. Start the answer with the name of the code that is being explained.",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't quite seem grammatical. If I were instructing a human, I would say, "If the selected code is a named symbol like a function or class, start your explanation with the name of that symbol." But we should check what yields the best results. Are there examples you can provide where this improves response quality?

What if the selection doesn't conform to the beginning of a named scope like a function or method (i.e., what if the selection is an unnamed block of code within a function body)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are there examples you can provide where this improves response quality?

Yeee. I added this because of the change to support visible content, if we don't add the last bit, sometimes it will just explain the code without letting you know which part of the code it is explaining, so I found adding this helps. Here is an example of how the result looks like without the last added bit:

Screenshot 2023-08-09 at 5 32 09 PM

When we specified to start with names for the same code:

Screenshot 2023-08-09 at 5 33 28 PM

It also doesn't affect code that doesn't has a name or non-function from what I've tested so far

Screenshot 2023-08-09 at 5 20 28 PM

Here is the answer after the last bit is added:
Screenshot 2023-08-09 at 5 24 33 PM

"context": {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/context/requiredContext/ perhaps?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Keeping this as it is for now if that's not an issue, as we already have users setting up commands with this field.

"currentFile": true,
"selection": true
"currentFile": true
}
},
"Generate Unit Tests": {
Expand All @@ -24,6 +23,10 @@
"currentFile": true,
"selection": true
}
},
"Code Smell": {
"slashCommand": "smell",
"prompt": "Please review and analyze the {languageName} code I have selected and identify potential areas for improvement related to code smells, readability, maintainability, performance, security, etc. Do not list issues already addressed in the given code. Focus on providing up to 5 constructive suggestions that could make the code more robust, efficient, or align with best practices. For each suggestion, provide a brief explanation of the potential benefits. After listing any recommendations, summarize if you found notable opportunities to enhance the code quality overall or if the code generally follows sound design principles. If no issues found, reply 'There are no errors.'"
}
}
}
4 changes: 2 additions & 2 deletions lib/shared/src/chat/prompts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ export interface CodyPromptContext {
filePath?: string
directoryPath?: string
none?: boolean
strict?: boolean // add additional prompt at the end to prevent hallucination
abeatrix marked this conversation as resolved.
Show resolved Hide resolved
}

export type CodyPromptType = 'workspace' | 'user' | 'default' | 'recently used'
Expand All @@ -74,8 +75,7 @@ export const ConfigFileName = {
vscode: '.vscode/cody.json',
}

// Default to include selection context only
// Default to not include codebase context
export const defaultCodyPromptContext: CodyPromptContext = {
codebase: false,
selection: true,
}
11 changes: 3 additions & 8 deletions lib/shared/src/chat/prompts/templates.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,3 @@
const selection_prompt = `
I have questions about this selected {languageName} code from {fileName}:
\`\`\`
{selectedText}
\`\`\`
`

const instruction_prompt = `Please follow these rules when answering my question:
- Your answers and suggestions should based on the shared context only.
- Do not suggest anything that would break the working code.
Expand All @@ -22,10 +15,12 @@ export const answers = {
}

export const prompts = {
selection: selection_prompt,
instruction: instruction_prompt,
}

export const rules = {
hallucination: prevent_hallucinations,
}

export const displayFileName = `\n
File: `
91 changes: 91 additions & 0 deletions lib/shared/src/chat/prompts/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
import path from 'path'

import { ContextMessage } from '../../codebase-context/messages'
import { ActiveTextEditorSelection } from '../../editor'
import { CHARS_PER_TOKEN, MAX_AVAILABLE_PROMPT_LENGTH, MAX_RECIPE_INPUT_TOKENS } from '../../prompt/constants'
import { truncateText } from '../../prompt/truncation'
import { getFileExtension, getNormalizedLanguageName } from '../recipes/helpers'
import { Interaction } from '../transcript/interaction'

import { CodyPromptContext } from '.'

/**
* Gets the name of the parent directory from a directory path.
*/
export const getParentDirName = (dirPath: string): string => path.basename(path.dirname(dirPath))
abeatrix marked this conversation as resolved.
Show resolved Hide resolved

/**
* Gets the current directory path from the file path param
*/
export const getCurrentDirPath = (filePath: string): string => path.dirname(filePath)
abeatrix marked this conversation as resolved.
Show resolved Hide resolved

/**
* Returns a Promise resolving to an Interaction object representing an error response from the assistant.
*
* @param errorMsg - The error message text to include in the assistant response.
* @param displayText - Optional human-readable display text for the request.
* @returns A Promise resolving to the Interaction object.
*/
export async function interactionWithAssistantError(errorMsg: string, displayText = ''): Promise<Interaction> {
abeatrix marked this conversation as resolved.
Show resolved Hide resolved
return Promise.resolve(
new Interaction(
{ speaker: 'human', displayText },
{ speaker: 'assistant', displayText: errorMsg, error: errorMsg },
Promise.resolve([]),
[]
)
)
}

/**
* Generates a prompt text string with the provided prompt and code selection.
*
* @param prompt - The prompt text to include after the code snippet.
* @param selection - The ActiveTextEditorSelection containing the code snippet.
* @returns The constructed prompt text string, or null if no selection provided.
*/
export function promptTextWithCodeSelection(
prompt: string,
selection?: ActiveTextEditorSelection | null
): string | null {
if (!selection) {
return null
}
const extension = getFileExtension(selection.fileName)
const languageName = getNormalizedLanguageName(extension)
const codePrefix = `I have this ${languageName} code selected in my editor from ${selection.fileName}:`

// Use the whole context window for the prompt because we're attaching no files
const maxTokenCount = MAX_AVAILABLE_PROMPT_LENGTH - (codePrefix.length + prompt.length) / CHARS_PER_TOKEN
const truncatedCode = truncateText(selection.selectedText, Math.min(maxTokenCount, MAX_RECIPE_INPUT_TOKENS))
const promptText = `${codePrefix}\n\n<selected>\n${truncatedCode}\n</selected>\n\n${prompt.replace(
'{languageName}',
languageName
)}`
return promptText
}

export async function makeInteraction(
abeatrix marked this conversation as resolved.
Show resolved Hide resolved
text: string,
displayText?: string,
contextMessages?: Promise<ContextMessage[]>,
assistantText?: string,
assistantDisplayText?: string
): Promise<Interaction> {
return Promise.resolve(
new Interaction(
{ speaker: 'human', text, displayText },
{ speaker: 'assistant', text: assistantText, displayText: assistantDisplayText },
Promise.resolve(contextMessages || []),
[]
)
)
}

export function isOnlySelectionRequired(contextConfig: CodyPromptContext, selectedText: string): boolean {
return (
contextConfig.selection !== false &&
selectedText.trim().length > 0 &&
Object.entries(contextConfig).length === 1
)
}
Loading
Loading