66import * as diff from 'diff'
77import { getLogger } from '../../shared/logger/logger'
88import * 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}
0 commit comments