154
return weightedSum / totalWeight;
155
}
157
>
/**
158
>
* Result of {@link computeWholeFileEditSurvival}.
159
>
*/
160
>
export interface IEditSurvivalScore {
161
>
/**
162
>
* 4-gram similarity between the current file content and the
163
>
* text the AI wrote. 1 = current text is identical to AI text,
164
>
* 0 = nothing in common.
165
>
*/
166
>
readonly fourGram: number;
167
>
/**
168
>
* 1 minus the fraction by which the user moved the text back
169
>
* toward the original. 1 = no revert (user kept or refined AI
170
>
* output), 0 = full revert to original.
171
>
*/
172
>
readonly noRevert: number;
173
>
}
174
>
175
>
/**
176
>
* Computes the whole-file revert score. 1 = file did not move back
177
>
* toward the original, 0 = file is back to the original. Used by both
178
>
* the whole-file and the chunked code paths, since revert detection is
179
>
* intrinsically a whole-file question (we want to know whether the
180
>
* user undid the change, not whether each AI-written region is still
181
>
* present).
182
>
*/
183
>
export function computeNoRevertScore(beforeText: string, afterText: string, currentText: string): number {
184
const aiSimilarity = compute4GramTextSimilarity(afterText, beforeText);
185
if (aiSimilarity === 1) {