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

Autocomplete: ship single-multiline requests #3176

Merged
merged 4 commits into from
Feb 15, 2024
Merged
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
2 changes: 0 additions & 2 deletions lib/shared/src/experimentation/FeatureFlagProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,6 @@ export enum FeatureFlag {
CodyAutocompleteHotStreak = 'cody-autocomplete-hot-streak',
// Connects to Cody Gateway directly and skips the Sourcegraph instance hop for completions
CodyAutocompleteFastPath = 'cody-autocomplete-fast-path',
// Trigger only one request for every multiline completion instead of three.
CodyAutocompleteSingleMultilineRequest = 'cody-autocomplete-single-multiline-request',

// Enable Cody PLG features on JetBrains
CodyProJetBrains = 'cody-pro-jetbrains',
Expand Down
1 change: 1 addition & 0 deletions vscode/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ This is a log of all notable changes to Cody for VS Code. [Unreleased] changes a
- Autocomplete: Enable the recent jaccard similarity improvements by default. [pull/3135](https://github.com/sourcegraph/cody/pull/3135)
- Autocomplete: Start retrieval phase earlier to improve latency. [pull/3149](https://github.com/sourcegraph/cody/pull/3149)
- Command: Leading slashes are removed from command names in the command menu. [pull/3061](https://github.com/sourcegraph/cody/pull/3061)
- Autocomplete: Trigger one LLM request instead of three for multiline completions to reduce the response latency. [pull/3176](https://github.com/sourcegraph/cody/pull/3176)

## [1.4.4]

Expand Down
1 change: 0 additions & 1 deletion vscode/src/completions/completion-provider-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ class CompletionProviderConfig {
FeatureFlag.CodyAutocompleteContextBfgMixed,
FeatureFlag.CodyAutocompleteDynamicMultilineCompletions,
FeatureFlag.CodyAutocompleteHotStreak,
FeatureFlag.CodyAutocompleteSingleMultilineRequest,
FeatureFlag.CodyAutocompleteFastPath,
FeatureFlag.CodyAutocompleteUserLatency,
FeatureFlag.CodyAutocompleteEagerCancellation,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,6 @@ describe('[getInlineCompletions] common', () => {
}
)
)
expect(requests).toHaveLength(3)
const messages = requests[0].messages
expect(messages.at(-1)!.text).toBe('<CODE5711>class Range {')
})
Expand Down
11 changes: 6 additions & 5 deletions vscode/src/completions/get-inline-completions-tests/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -362,13 +362,14 @@ expect.extend({
const { isNot } = this

return {
pass:
requests.length === 3 && isEqual(requests[0]?.stopSequences, MULTI_LINE_STOP_SEQUENCES),
pass: isEqual(requests[0]?.stopSequences, MULTI_LINE_STOP_SEQUENCES),
message: () => `Completion requests are${isNot ? ' not' : ''} multi-line`,
actual: requests.map(r => ({ stopSequences: r.stopSequences })),
expected: Array.from({ length: 3 }).map(() => ({
stopSequences: MULTI_LINE_STOP_SEQUENCES,
})),
expected: [
{
stopSequences: MULTI_LINE_STOP_SEQUENCES,
},
],
}
},
})
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { describe, expect, it } from 'vitest'
import type { CompletionParameters } from '@sourcegraph/cody-shared'

import { completion } from '../test-helpers'
import { MULTILINE_STOP_SEQUENCE } from '../text-processing'

import { getInlineCompletionsInsertText, params } from './helpers'

Expand Down Expand Up @@ -37,8 +36,7 @@ describe('[getInlineCompletions] languages', () => {
}
)
)
expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"print(i)
elif i % 3 == 0:
Expand Down Expand Up @@ -79,8 +77,7 @@ describe('[getInlineCompletions] languages', () => {
}
)
)
expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"System.out.println(i);
} else if (i % 3 == 0) {
Expand Down Expand Up @@ -130,8 +127,7 @@ describe('[getInlineCompletions] languages', () => {
}
)
)
expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"Console.WriteLine(i);
}"
Expand Down Expand Up @@ -169,8 +165,7 @@ describe('[getInlineCompletions] languages', () => {
}
)
)
expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"std::cout << i;
} else if (i % 3 == 0) {
Expand Down Expand Up @@ -212,8 +207,8 @@ describe('[getInlineCompletions] languages', () => {
}
)
)
expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)

expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"printf("%d", i);
} else if (i % 3 == 0) {
Expand Down Expand Up @@ -256,8 +251,7 @@ describe('[getInlineCompletions] languages', () => {
)
)

expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"echo $i;
} else if ($i % 3 == 0) {
Expand Down Expand Up @@ -300,8 +294,7 @@ describe('[getInlineCompletions] languages', () => {
)
)

expect(requests).toHaveLength(3)
expect(requests[0].stopSequences).not.toContain(MULTILINE_STOP_SEQUENCE)
expect(requests).toBeMultiLine()
expect(items[0]).toMatchInlineSnapshot(`
"print(i);
} else if (i % 3 == 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,10 @@ for (const isTreeSitterEnabled of cases) {
console.log('bar')
}┤
┴┴┴┴`,
]
],
{
providerOptions: { n: 2 },
}
)
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ for (const isTreeSitterEnabled of cases) {
completion`
├console.log('foo')┤
`,
]
],
{
providerOptions: { n: 3 },
}
)
)

Expand Down Expand Up @@ -175,7 +178,10 @@ for (const isTreeSitterEnabled of cases) {
completions.map(completion => ({
completion,
stopReason: 'unknown',
}))
})),
{
providerOptions: { n: 3 },
}
)
)

Expand Down Expand Up @@ -215,37 +221,29 @@ for (const isTreeSitterEnabled of cases) {
`,
['array) {\nreturn array.sort()\n} function two() {}', 'array) new\n']
)
const [completion] = completions.map(c =>
pick(c, ['insertText', 'nodeTypes', 'nodeTypesWithCompletion', 'parseErrorCount'])
)

expect(
completions.map(c =>
pick(c, [
'insertText',
'nodeTypes',
'nodeTypesWithCompletion',
'parseErrorCount',
])
)
).toMatchInlineSnapshot(`
[
{
"insertText": "array) {",
"nodeTypes": {
"atCursor": "(",
"grandparent": "function_signature",
"greatGrandparent": "program",
"lastAncestorOnTheSameLine": "function_signature",
"parent": "formal_parameters",
},
"nodeTypesWithCompletion": {
"atCursor": "(",
"grandparent": "function_declaration",
"greatGrandparent": "program",
"lastAncestorOnTheSameLine": "function_declaration",
"parent": "formal_parameters",
},
"parseErrorCount": 0,
expect(completion).toMatchInlineSnapshot(`
{
"insertText": "array) {",
"nodeTypes": {
"atCursor": "(",
"grandparent": "function_signature",
"greatGrandparent": "program",
"lastAncestorOnTheSameLine": "function_signature",
"parent": "formal_parameters",
},
"nodeTypesWithCompletion": {
"atCursor": "(",
"grandparent": "function_declaration",
"greatGrandparent": "program",
"lastAncestorOnTheSameLine": "function_declaration",
"parent": "formal_parameters",
},
]
"parseErrorCount": 0,
}
`)
})

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,18 +25,15 @@ describe('[getInlineCompletions] triggers', () => {

it('middle of line', async () => {
const result = await getInlineCompletions(
params('function bubbleSort(█)', [completion`array) {`, completion`items) {`])
params('function bubbleSort(█)', [completion`array) {`])
)

expect(
result?.items.map(item => ({
insertText: item.insertText,
range: item.range,
}))
).toEqual([
{ insertText: 'array) {', range: range(0, 20, 0, 21) },
{ insertText: 'items) {', range: range(0, 20, 0, 21) },
])
).toEqual([{ insertText: 'array) {', range: range(0, 20, 0, 21) }])
})

describe('same line suffix behavior', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,7 @@ import { getInlineCompletionsInsertText, params } from './helpers'

describe('[getInlineCompletions] windows ', () => {
it('works works with \\r\\n line terminators', async () => {
const completion1 = completion`
├console.log('foo')
}

add() {
console.log('bar')
}┤
┴┴┴┴`
const completion2 = completion`
const completionResponse = completion`
├if (foo) {
console.log('foo1');
}
Expand All @@ -26,8 +18,7 @@ describe('[getInlineCompletions] windows ', () => {
}┤
┴┴┴┴`

completion1.completion = windowsify(completion1.completion)
completion2.completion = windowsify(completion2.completion)
completionResponse.completion = windowsify(completionResponse.completion)

const items = await getInlineCompletionsInsertText(
params(
Expand All @@ -38,12 +29,11 @@ describe('[getInlineCompletions] windows ', () => {
}
}
`),
[completion1, completion2]
[completionResponse]
)
)

expect(items[0]).toBe("if (foo) {\n console.log('foo1');\n }")
expect(items[1]).toBe("console.log('foo')")
})
})

Expand Down
21 changes: 7 additions & 14 deletions vscode/src/completions/get-inline-completions.ts
Original file line number Diff line number Diff line change
@@ -1,12 +1,7 @@
import type * as vscode from 'vscode'
import type { URI } from 'vscode-uri'

import {
FeatureFlag,
getActiveTraceAndSpanId,
isAbortError,
wrapInActiveSpan,
} from '@sourcegraph/cody-shared'
import { getActiveTraceAndSpanId, isAbortError, wrapInActiveSpan } from '@sourcegraph/cody-shared'

import { logError } from '../log'
import type { CompletionIntent } from '../tree-sitter/query-sdk'
Expand Down Expand Up @@ -418,23 +413,21 @@ function getCompletionProvider(params: GetCompletionProvidersParams): Provider {
firstCompletionTimeout: 1900,
}

// Show more if manually triggered (but only showing 1 is faster, so we use it
// in the automatic trigger case).
const n = triggerKind === TriggerKind.Automatic ? 1 : 3

if (docContext.multilineTrigger) {
return providerConfig.create({
...sharedProviderOptions,
n: completionProviderConfig.getPrefetchedFlag(
FeatureFlag.CodyAutocompleteSingleMultilineRequest
)
? 1
: 3, // 3 vs. 1 does not meaningfully affect perf
n,
multiline: true,
})
}

return providerConfig.create({
...sharedProviderOptions,
// Show more if manually triggered (but only showing 1 is faster, so we use it
// in the automatic trigger case).
n: triggerKind === TriggerKind.Automatic ? 1 : 3,
n,
multiline: false,
})
}
Expand Down
Loading