Skip to content

Commit

Permalink
Autocomplete: add providerModel to stage counter logger (sourcegrap…
Browse files Browse the repository at this point in the history
  • Loading branch information
valerybugakov committed Jun 28, 2024
1 parent d69fe54 commit e17dceb
Show file tree
Hide file tree
Showing 3 changed files with 97 additions and 15 deletions.
2 changes: 2 additions & 0 deletions vscode/src/completions/inline-completion-item-provider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,8 @@ export class InlineCompletionItemProvider
noInlineAccept: config.noInlineAccept ?? false,
}

autocompleteStageCounterLogger.setProviderModel(config.providerConfig.model)

if (this.config.completeSuggestWidgetSelection) {
// This must be set to true, or else the suggest widget showing will suppress inline
// completions. Note that the VS Code proposed API inlineCompletionsAdditions contains
Expand Down
85 changes: 73 additions & 12 deletions vscode/src/services/autocomplete-stage-counter-logger.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,27 +18,19 @@ describe('AutocompleteStageCounter', () => {
vi.clearAllTimers()
})

it('returns initial state after LOG_INTERVAL', () => {
it('does not log empty counter events', () => {
logger.setProviderModel('test-model')
vi.advanceTimersByTime(LOG_INTERVAL - 1)

expect(recordSpy).not.toHaveBeenCalled()

vi.advanceTimersByTime(1)

expect(recordSpy).toHaveBeenCalledWith('cody.completion.stageCounter', 'flush', {
metadata: {
preLastCandidate: 0,
preCache: 0,
preDebounce: 0,
preContextRetrieval: 0,
preNetworkRequest: 0,
preFinalCancellationCheck: 0,
preVisibilityCheck: 0,
},
})
expect(recordSpy).not.toHaveBeenCalled()
})

it('records state changes', () => {
logger.setProviderModel('test-model')
logger.record('preLastCandidate')
logger.record('preCache')
logger.record('preDebounce')
Expand All @@ -59,10 +51,12 @@ describe('AutocompleteStageCounter', () => {
preFinalCancellationCheck: 1,
preVisibilityCheck: 1,
},
privateMetadata: { providerModel: 'test-model' },
})
})

it('resets state after flushing', () => {
logger.setProviderModel('test-model')
logger.record('preLastCandidate')
logger.record('preCache')
logger.record('preCache')
Expand All @@ -79,6 +73,7 @@ describe('AutocompleteStageCounter', () => {
preFinalCancellationCheck: 0,
preVisibilityCheck: 0,
},
privateMetadata: { providerModel: 'test-model' },
})

logger.record('preDebounce')
Expand All @@ -95,6 +90,72 @@ describe('AutocompleteStageCounter', () => {
preFinalCancellationCheck: 0,
preVisibilityCheck: 0,
},
privateMetadata: { providerModel: 'test-model' },
})
})

it('includes providerModel in privateMetadata when set', () => {
logger.setProviderModel('test-model')
logger.record('preLastCandidate')

vi.advanceTimersByTime(LOG_INTERVAL)

expect(recordSpy).toHaveBeenCalledWith('cody.completion.stageCounter', 'flush', {
metadata: expect.any(Object),
privateMetadata: { providerModel: 'test-model' },
})
})

it('flushes when providerModel changes', () => {
logger.setProviderModel('model-1')
logger.record('preLastCandidate')

logger.setProviderModel('model-2')

expect(recordSpy).toHaveBeenCalledWith('cody.completion.stageCounter', 'flush', {
metadata: {
preLastCandidate: 1,
preCache: 0,
preDebounce: 0,
preContextRetrieval: 0,
preNetworkRequest: 0,
preFinalCancellationCheck: 0,
preVisibilityCheck: 0,
},
privateMetadata: { providerModel: 'model-1' },
})
})

it('does not flush when setting the same providerModel', () => {
logger.setProviderModel('test-model')
logger.record('preLastCandidate')

logger.setProviderModel('test-model')

expect(recordSpy).not.toHaveBeenCalled()
})

it('includes latest providerModel in flush after changes', () => {
logger.setProviderModel('model-1')
logger.record('preLastCandidate')

logger.setProviderModel('model-2')
logger.record('preCache')

vi.advanceTimersByTime(LOG_INTERVAL)

expect(recordSpy).toHaveBeenCalledTimes(2)
expect(recordSpy).toHaveBeenLastCalledWith('cody.completion.stageCounter', 'flush', {
metadata: {
preLastCandidate: 0,
preCache: 1,
preDebounce: 0,
preContextRetrieval: 0,
preNetworkRequest: 0,
preFinalCancellationCheck: 0,
preVisibilityCheck: 0,
},
privateMetadata: { providerModel: 'model-2' },
})
})
})
25 changes: 22 additions & 3 deletions vscode/src/services/autocomplete-stage-counter-logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,20 +19,34 @@ const INITIAL_STATE = {

export class AutocompleteStageCounter implements vscode.Disposable {
private nextTimeoutId: NodeJS.Timeout | null = null
private providerModel: string | null = null
private currentState = { ...INITIAL_STATE }

constructor() {
this.nextTimeoutId = setTimeout(() => this.flush(), LOG_INTERVAL)
}

public setProviderModel(providerModel: string): void {
// Flush the current counter on model change.
if (this.providerModel !== null && this.providerModel !== providerModel) {
this.flush()
}

this.providerModel = providerModel
}

public flush(): void {
this.nextTimeoutId = null
const stateToLog = this.currentState
this.currentState = { ...INITIAL_STATE }

telemetryRecorder.recordEvent('cody.completion.stageCounter', 'flush', {
metadata: stateToLog,
})
// Do not log empty counter events.
if (Object.values(stateToLog).some(count => count > 0)) {
telemetryRecorder.recordEvent('cody.completion.stageCounter', 'flush', {
metadata: stateToLog,
privateMetadata: { providerModel: this.providerModel },
})
}

this.nextTimeoutId = setTimeout(() => this.flush(), LOG_INTERVAL)
}
Expand All @@ -41,6 +55,11 @@ export class AutocompleteStageCounter implements vscode.Disposable {
* Records the occurrence of a specific stage in the autocompletion generation pipeline.
*/
public record(state: keyof typeof this.currentState): void {
if (!this.providerModel) {
// Do nothing if provider model is not set.
return
}

this.currentState[state]++
}

Expand Down

0 comments on commit e17dceb

Please sign in to comment.