Skip to content

Commit b935964

Browse files
committed
enforce supplemental context char limit
1 parent fa6b40b commit b935964

File tree

4 files changed

+53
-21
lines changed

4 files changed

+53
-21
lines changed

packages/core/src/codewhisperer/activation.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ import { activateNextEditPrediction } from './nextEditPrediction/activation'
100100
let localize: nls.LocalizeFunc
101101

102102
export async function activate(context: ExtContext): Promise<void> {
103-
// Activate the Next Edit Prediction system
104103
activateNextEditPrediction(context)
105104
localize = nls.loadMessageBundle()
106105

packages/core/src/codewhisperer/models/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -934,7 +934,7 @@ export const testGenExcludePatterns = [
934934

935935
export const predictionTrackerDefaultConfig = {
936936
maxFiles: 25,
937-
maxStorageSizeKb: 50000,
937+
maxStorageSizeKb: 10000,
938938
debounceIntervalMs: 2000,
939939
maxAgeMs: 30000,
940940
maxSupplementalContext: 15,

packages/core/src/codewhisperer/nextEditPrediction/diffContextGenerator.ts

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,20 @@
66
import * as diff from 'diff'
77
import { getLogger } from '../../shared/logger/logger'
88
import * as codewhispererClient from '../client/codewhisperer'
9+
import { supplementalContextMaxTotalLength, charactersLimit } from '../models/constants'
910

1011
/**
1112
* Generates a unified diff format between old and new file contents
12-
*
13-
* @param oldFilePath - Path of the old file
14-
* @param newFilePath - Path of the new file
15-
* @param oldContent - Content of the old file
16-
* @param newContent - Content of the new file
17-
* @param oldTimestamp - Timestamp of the old file version
18-
* @param newTimestamp - Timestamp of the new file version
19-
* @param contextSize - Number of context lines to include (default: 3)
20-
* @returns Unified diff as a string
2113
*/
22-
async function generateUnifiedDiffWithTimestamps(
14+
function generateUnifiedDiffWithTimestamps(
2315
oldFilePath: string,
2416
newFilePath: string,
2517
oldContent: string,
2618
newContent: string,
2719
oldTimestamp: number,
2820
newTimestamp: number,
2921
contextSize: number = 3
30-
): Promise<string> {
22+
): string {
3123
const patchResult = diff.createTwoFilesPatch(
3224
oldFilePath,
3325
newFilePath,
@@ -66,12 +58,12 @@ export interface SnapshotContent {
6658
* U1: udiff of T_0 and T_2
6759
* U2: udiff of T_0 and T_3
6860
*/
69-
export async function generateDiffContexts(
61+
export function generateDiffContexts(
7062
filePath: string,
7163
currentContent: string,
7264
snapshotContents: SnapshotContent[],
7365
maxContexts: number
74-
): Promise<codewhispererClient.SupplementalContext[]> {
66+
): codewhispererClient.SupplementalContext[] {
7567
if (snapshotContents.length === 0) {
7668
return []
7769
}
@@ -82,7 +74,7 @@ export async function generateDiffContexts(
8274
for (let i = snapshotContents.length - 1; i >= 0; i--) {
8375
const snapshot = snapshotContents[i]
8476
try {
85-
const unifiedDiff = await generateUnifiedDiffWithTimestamps(
77+
const unifiedDiff = generateUnifiedDiffWithTimestamps(
8678
snapshot.filePath,
8779
filePath,
8880
snapshot.content,
@@ -106,10 +98,51 @@ export async function generateDiffContexts(
10698
}
10799
}
108100

109-
// Limit the number of supplemental contexts based on config
110-
if (supplementalContexts.length > maxContexts) {
111-
return supplementalContexts.slice(0, maxContexts)
101+
return trimSupplementalContexts(supplementalContexts, maxContexts)
102+
}
103+
104+
/**
105+
* Trims the supplementalContexts array to ensure it doesn't exceed the max number
106+
* of contexts or total character length limit
107+
*
108+
* @param supplementalContexts - Array of SupplementalContext objects (already sorted with newest first)
109+
* @param maxContexts - Maximum number of supplemental contexts allowed
110+
* @returns Trimmed array of SupplementalContext objects
111+
*/
112+
function trimSupplementalContexts(
113+
supplementalContexts: codewhispererClient.SupplementalContext[],
114+
maxContexts: number
115+
): codewhispererClient.SupplementalContext[] {
116+
if (supplementalContexts.length === 0) {
117+
return supplementalContexts
118+
}
119+
120+
// First filter out any individual context that exceeds the character limit
121+
let result = supplementalContexts.filter((context) => {
122+
return context.content.length <= charactersLimit
123+
})
124+
125+
// Then limit by max number of contexts
126+
if (result.length > maxContexts) {
127+
result = result.slice(0, maxContexts)
128+
}
129+
130+
// Lastly enforce total character limit
131+
let totalLength = 0
132+
let i = 0
133+
134+
while (i < result.length) {
135+
totalLength += result[i].content.length
136+
if (totalLength > supplementalContextMaxTotalLength) {
137+
break
138+
}
139+
i++
140+
}
141+
142+
if (i === result.length) {
143+
return result
112144
}
113145

114-
return supplementalContexts
146+
const trimmedContexts = result.slice(0, i)
147+
return trimmedContexts
115148
}

packages/core/src/test/codewhisperer/nextEditPrediction/PredictionTracker.test.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ describe('PredictionTracker', function () {
7474

7575
it('should save snapshot to storage', async function () {
7676
const timestamp = Date.now()
77-
const storageKey = `${filePath}-${timestamp}`
77+
const storageKey = `${filePath.replace(/\//g, '__')}-${timestamp}`
7878
await (tracker as any).takeSnapshot(filePath, previousContent)
7979

8080
// Check if the snapshot was saved to storage

0 commit comments

Comments
 (0)