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

use the accurate docContext and persist repo visibility using local storage #5767

Open
wants to merge 2 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
14 changes: 7 additions & 7 deletions lib/shared/src/experimentation/FeatureFlagProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ export enum FeatureFlag {
CodyAutocompleteDataCollectionFlag = 'cody-autocomplete-data-collection-flag',

// Enable various feature flags to experiment with FIM trained fine-tuned models via Fireworks
CodyAutocompleteFIMModelExperimentBaseFeatureFlag = 'cody-autocomplete-fim-model-experiment-flag-v2',
CodyAutocompleteFIMModelExperimentControl = 'cody-autocomplete-fim-model-experiment-control-v2',
CodyAutocompleteFIMModelExperimentCurrentBest = 'cody-autocomplete-fim-model-experiment-current-best-v2',
CodyAutocompleteFIMModelExperimentVariant1 = 'cody-autocomplete-fim-model-experiment-variant-1-v2',
CodyAutocompleteFIMModelExperimentVariant2 = 'cody-autocomplete-fim-model-experiment-variant-2-v2',
CodyAutocompleteFIMModelExperimentVariant3 = 'cody-autocomplete-fim-model-experiment-variant-3-v2',
CodyAutocompleteFIMModelExperimentVariant4 = 'cody-autocomplete-fim-model-experiment-variant-4-v2',
CodyAutocompleteFIMModelExperimentBaseFeatureFlag = 'cody-autocomplete-fim-model-experiment-flag',
CodyAutocompleteFIMModelExperimentControl = 'cody-autocomplete-fim-model-experiment-control',
CodyAutocompleteFIMModelExperimentCurrentBest = 'cody-autocomplete-fim-model-experiment-current-best',
CodyAutocompleteFIMModelExperimentVariant1 = 'cody-autocomplete-fim-model-experiment-variant-1',
CodyAutocompleteFIMModelExperimentVariant2 = 'cody-autocomplete-fim-model-experiment-variant-2',
CodyAutocompleteFIMModelExperimentVariant3 = 'cody-autocomplete-fim-model-experiment-variant-3',
CodyAutocompleteFIMModelExperimentVariant4 = 'cody-autocomplete-fim-model-experiment-variant-4',
CodyAutocompleteDisableLowPerfLangDelay = 'cody-autocomplete-disable-low-perf-lang-delay',
// Enables Claude 3 if the user is in our holdout group
CodyAutocompleteClaude3 = 'cody-autocomplete-claude-3',
Expand Down
3 changes: 3 additions & 0 deletions vscode/src/completions/inline-completion-item-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -843,10 +843,13 @@ export class InlineCompletionItemProvider
takeSuggestWidgetSelectionIntoAccount,
undefined
)
completion.requestParams.docContext.position
if (isStillVisible) {
suggestionEvent.markAsRead({
document: invokedDocument,
position: invokedPosition,
docPrefix: completion.requestParams.docContext.completePrefix,
docSuffix: completion.requestParams.docContext.completeSuffix,
})
}
}, this.COMPLETION_VISIBLE_DELAY_MS)
Expand Down
28 changes: 24 additions & 4 deletions vscode/src/completions/logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,12 @@ describe('logger', () => {
isDotComUser: false,
})
const suggestionEvent = CompletionLogger.prepareSuggestionEvent({ id })
suggestionEvent?.markAsRead({ document, position })
suggestionEvent?.markAsRead({
document,
position,
docPrefix: defaultRequestParams.docContext.completePrefix,
docSuffix: defaultRequestParams.docContext.completeSuffix,
})
CompletionLogger.accepted(id, document, item, range(0, 0, 0, 0), false)

expect(recordSpy).toHaveBeenCalledWith('cody.completion', 'suggested', {
Expand Down Expand Up @@ -111,7 +116,12 @@ describe('logger', () => {
isDotComUser: false,
})
const firstSuggestionEvent = CompletionLogger.prepareSuggestionEvent({ id: id1 })
firstSuggestionEvent?.markAsRead({ document, position })
firstSuggestionEvent?.markAsRead({
document,
position,
docPrefix: defaultRequestParams.docContext.completePrefix,
docSuffix: defaultRequestParams.docContext.completeSuffix,
})

const loggerItem = CompletionLogger.getCompletionEvent(id1)
const completionId = loggerItem?.params.id
Expand All @@ -129,7 +139,12 @@ describe('logger', () => {
isDotComUser: false,
})
const secondSuggestionEvent = CompletionLogger.prepareSuggestionEvent({ id: id2 })
secondSuggestionEvent?.markAsRead({ document, position })
secondSuggestionEvent?.markAsRead({
document,
position,
docPrefix: defaultRequestParams.docContext.completePrefix,
docSuffix: defaultRequestParams.docContext.completeSuffix,
})
CompletionLogger.accepted(id2, document, item, range(0, 0, 0, 0), false)

const loggerItem2 = CompletionLogger.getCompletionEvent(id2)
Expand All @@ -154,7 +169,12 @@ describe('logger', () => {
isDotComUser: false,
})
const thirdSuggestionEvent = CompletionLogger.prepareSuggestionEvent({ id: id3 })
thirdSuggestionEvent?.markAsRead({ document, position })
thirdSuggestionEvent?.markAsRead({
document,
position,
docPrefix: defaultRequestParams.docContext.completePrefix,
docSuffix: defaultRequestParams.docContext.completeSuffix,
})

const loggerItem3 = CompletionLogger.getCompletionEvent(id3)
expect(loggerItem3?.params.id).not.toBe(completionId)
Expand Down
17 changes: 14 additions & 3 deletions vscode/src/completions/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -775,7 +775,9 @@ function getInlineContextItemContext(
function suggestionDocumentDiffTracker(
interactionId: CompletionAnalyticsID,
document: vscode.TextDocument,
position: vscode.Position
position: vscode.Position,
docPrefix: string,
docSuffix: string
): void {
// If user is not in the same document, we don't track the diff.
if (document.uri.scheme !== 'file') {
Expand All @@ -786,12 +788,13 @@ function suggestionDocumentDiffTracker(
}
// Offset around the current cursor position to track the diff
const offsetBytes = 1024 * 128

const startPosition = document.positionAt(Math.max(0, document.offsetAt(position) - offsetBytes))
const endPosition = document.positionAt(
Math.min(document.getText().length, document.offsetAt(position) + offsetBytes)
)
const trackingRange = new vscode.Range(startPosition, endPosition)
const documentText = document.getText(trackingRange)
const documentText = docPrefix.slice(-offsetBytes) + docSuffix.slice(0, offsetBytes)

const persistenceTimeoutList = [
20 * 1000, // 20 seconds
Expand All @@ -815,6 +818,8 @@ function suggestionDocumentDiffTracker(
type SuggestionMarkReadParam = {
document: vscode.TextDocument
position: vscode.Position
docPrefix: string
docSuffix: string
}

// Suggested completions will not be logged immediately. Instead, we log them when we either hide
Expand Down Expand Up @@ -872,7 +877,13 @@ export function prepareSuggestionEvent({
isDotCom(authStatus.endpoint || '') &&
event.params.inlineCompletionItemContext?.isRepoPublic
) {
suggestionDocumentDiffTracker(event.params.id, param.document, param.position)
suggestionDocumentDiffTracker(
event.params.id,
param.document,
param.position,
param.docPrefix,
param.docSuffix
)
}
},
}
Expand Down
170 changes: 170 additions & 0 deletions vscode/src/completions/model-helpers/__tests__/codeqwen.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { describe, expect, it } from 'vitest'

import { isWindows } from '@sourcegraph/cody-shared'

import { completionParams, contextSnippets } from './test-data'

import { CodeQwen } from '../codeqwen'

describe('CodeQwen', () => {
describe.skipIf(isWindows())('getMessages', () => {
it('returns the prompt with the correct intro snippets', () => {
const model = new CodeQwen()
const { docContext, document, provider } = completionParams

const result = model.getMessages({
document,
docContext,
snippets: contextSnippets,
promptChars: provider.contextSizeHints.totalChars,
})

expect(result).toMatchInlineSnapshot(`
[
{
"speaker": "human",
"text": "<|file_sep|>codebase/context1.ts
function contextSnippetOne() {}
<|file_sep|>codebase/context2.ts
const contextSnippet2 = {}
Additional documentation for \`ContextParams\`:
interface ContextParams {}
<|file_sep|>codebase/test.ts
<|fim_prefix|>console.log(prefix line: 1)
console.log(prefix line: 2)
console.log(prefix line: 3)
console.log(prefix line: 4)
console.log(prefix line: 5)
console.log(prefix line: 6)
console.log(prefix line: 7)
console.log(prefix line: 8)
console.log(prefix line: 9)
console.log(prefix line: 10)
console.log(prefix line: 11)
console.log(prefix line: 12)
console.log(prefix line: 13)
console.log(prefix line: 14)
console.log(prefix line: 15)
console.log(prefix line: 16)
console.log(prefix line: 17)
console.log(prefix line: 18)
console.log(prefix line: 19)
console.log(prefix line: 20)
console.log(prefix line: 21)
console.log(prefix line: 22)
console.log(prefix line: 23)
console.log(prefix line: 24)
console.log(prefix line: 25)
console.log(prefix line: 26)
console.log(prefix line: 27)
console.log(prefix line: 28)
console.log(prefix line: 29)
console.log(prefix line: 30)
console.log(prefix line: 31)
console.log(prefix line: 32)
console.log(prefix line: 33)
console.log(prefix line: 34)
console.log(prefix line: 35)
console.log(prefix line: 36)
console.log(prefix line: 37)
console.log(prefix line: 38)
console.log(prefix line: 39)
console.log(prefix line: 40)
console.log(prefix line: 41)
console.log(prefix line: 42)
console.log(prefix line: 43)
console.log(prefix line: 44)
console.log(prefix line: 45)
console.log(prefix line: 46)
console.log(prefix line: 47)
console.log(prefix line: 48)
console.log(prefix line: 49)
console.log(prefix line: 50)
console.log(prefix line: 51)
console.log(prefix line: 52)
console.log(prefix line: 53)
console.log(prefix line: 54)
console.log(prefix line: 55)
console.log(prefix line: 56)
console.log(prefix line: 57)
console.log(prefix line: 58)
console.log(prefix line: 59)
console.log(prefix line: 60)
console.log(prefix line: 61)
console.log(prefix line: 62)
console.log(prefix line: 63)
console.log(prefix line: 64)
console.log(prefix line: 65)
console.log(prefix line: 66)
console.log(prefix line: 67)
console.log(prefix line: 68)
console.log(prefix line: 69)
console.log(prefix line: 70)
console.log(prefix line: 71)
console.log(prefix line: 72)
console.log(prefix line: 73)
console.log(prefix line: 74)
console.log(prefix line: 75)
console.log(prefix line: 76)
console.log(prefix line: 77)
console.log(prefix line: 78)
console.log(prefix line: 79)
console.log(prefix line: 80)
console.log(prefix line: 81)
console.log(prefix line: 82)
console.log(prefix line: 83)
console.log(prefix line: 84)
console.log(prefix line: 85)
console.log(prefix line: 86)
console.log(prefix line: 87)
console.log(prefix line: 88)
console.log(prefix line: 89)
console.log(prefix line: 90)
console.log(prefix line: 91)
console.log(prefix line: 92)
console.log(prefix line: 93)
console.log(prefix line: 94)
console.log(prefix line: 95)
console.log(prefix line: 96)
console.log(prefix line: 97)
console.log(prefix line: 98)
console.log(prefix line: 99)
console.log(prefix line: 100)
function myFunction() {
console.log(1)
console.log(2)
console.log(3)
console.log(4)
<|fim_suffix|>
}
console.log(suffix line: 1)
console.log(suffix line: 2)
console.log(suffix line: 3)
console.log(suffix line: 4)
console.log(suffix line: 5)
console.log(suffix line: 6)
console.log(suffix line: 7)
console.log(suffix line: 8)
console.log(suffix line: 9)
console.log(suffix line: 10)
console.log(suffix line: 11)
console.log(suffix line: 12)
console.log(suffix line: 13)
console.log(suffix line: 14)
console.log(suffix line: 15)
console.log(suffix line: 16)
console.log(suffix line: 17)
console.log(suffix line: 18)
console.log(suffix line: 19)
console.log(suffix line: 20)
console.log(suffix line: 21)
console.log(suffix line: 22)
console.log(suffix line: 23)
console.log(suffix line: 24)
console.log(suffix line: 25)<|fim_middle|>",
},
]
`)
})
})
})
82 changes: 82 additions & 0 deletions vscode/src/completions/model-helpers/codeqwen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import {
type AutocompleteFileContextSnippet,
type OllamaGenerateParameters,
PromptString,
ps,
} from '@sourcegraph/cody-shared'
import {
DefaultModel,
type FormatIntroSnippetsParams,
type FormatPromptParams,
type GetOllamaPromptParams,
} from './default'

const EOT_CODEQWEN = '<|endoftext|>'

export class CodeQwen extends DefaultModel {
stopSequences = [
'<|repo_name|>',
'<|file_sep|>',
'<|fim_prefix|>',
'<|fim_suffix|>',
'<|fim_middle|>',
EOT_CODEQWEN,
]

getOllamaPrompt(promptContext: GetOllamaPromptParams): PromptString {
const { context, currentFileNameComment, prefix, suffix } = promptContext

const infillPrefix = context.concat(currentFileNameComment, prefix)

return ps`<|fim_prefix|>${infillPrefix}<|fim_suffix|>${suffix}<|fim_middle|>`
}

getOllamaRequestOptions(isMultiline: boolean): OllamaGenerateParameters {
const params = {
stop: ['\n', ...this.stopSequences],
temperature: 0.2,
top_k: 40,
top_p: 0.8,
num_predict: 256,
num_gpu: 99,
repeat_penalty: 1.1,
}

if (isMultiline) {
params.stop = ['\n\n', ...this.stopSequences]
}

return params
}

postProcess(content: string): string {
return content.replace(EOT_CODEQWEN, '')
}

formatIntroSnippets(params: FormatIntroSnippetsParams): PromptString {
let introPrompt = ps`${PromptString.join(params.intro, ps`\n`)}`
if (introPrompt.length > 0) {
introPrompt = ps`${introPrompt}\n`
}
return introPrompt
}

fileSnippetToPromptString(snippet: AutocompleteFileContextSnippet): PromptString {
const { content } = PromptString.fromAutocompleteContextSnippet(snippet)
return ps`<|file_sep|>${PromptString.fromDisplayPath(snippet.uri)}\n${content}`
}

formatPrompt(params: FormatPromptParams): PromptString {
// Prompt format for CodeQwen in technical report: https://arxiv.org/pdf/2409.12186
const { intro, prefix, suffix, repoName, fileName } = params
let introPrefix = ps``

Check failure on line 72 in vscode/src/completions/model-helpers/codeqwen.ts

View workflow job for this annotation

GitHub Actions / build

'introPrefix' is declared but its value is never read.

Check failure on line 72 in vscode/src/completions/model-helpers/codeqwen.ts

View workflow job for this annotation

GitHub Actions / test-unit (ubuntu, 20)

'introPrefix' is declared but its value is never read.

Check failure on line 72 in vscode/src/completions/model-helpers/codeqwen.ts

View workflow job for this annotation

GitHub Actions / test-unit (ubuntu, 18)

'introPrefix' is declared but its value is never read.
if (intro.length > 0) {
introPrefix = ps`${intro}\n`
}
const prompt = ps`${intro}<|file_sep|>${fileName}\n<|fim_prefix|>${prefix}<|fim_suffix|>${suffix}<|fim_middle|>`
if (repoName) {
return ps`<|repo_name|>${repoName}\n${prompt}`
}
return prompt
}
}
Loading
Loading