feat(telemetry): Add character counts to diff stats (#7619)

Co-authored-by: Shnatu <snatu@google.com>
Co-authored-by: cornmander <shikhman@google.com>
This commit is contained in:
Shardul Natu
2025-09-03 15:51:20 -07:00
committed by GitHub
parent 6bb944f942
commit af522f21fb
4 changed files with 75 additions and 19 deletions

View File

@@ -18,12 +18,16 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 0,
ai_removed_lines: 0,
model_added_chars: 0,
model_removed_chars: 0,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
it('should correctly report AI additions', () => {
it('should correctly report model additions', () => {
const oldStr = 'line1\nline2\n';
const aiStr = 'line1\nline2\nline3\n';
const userStr = 'line1\nline2\nline3\n';
@@ -31,12 +35,16 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 0,
model_added_chars: 5,
model_removed_chars: 0,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
it('should correctly report AI removals', () => {
it('should correctly report model removals', () => {
const oldStr = 'line1\nline2\nline3\n';
const aiStr = 'line1\nline3\n';
const userStr = 'line1\nline3\n';
@@ -44,12 +52,16 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 0,
ai_removed_lines: 1,
model_added_chars: 0,
model_removed_chars: 5,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
it('should correctly report AI modifications', () => {
it('should correctly report model modifications', () => {
const oldStr = 'line1\nline2\nline3\n';
const aiStr = 'line1\nline_two\nline3\n';
const userStr = 'line1\nline_two\nline3\n';
@@ -57,8 +69,12 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 1,
model_added_chars: 8,
model_removed_chars: 5,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
@@ -70,8 +86,12 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 0,
model_added_chars: 5,
model_removed_chars: 0,
user_added_lines: 1,
user_removed_lines: 0,
user_added_chars: 5,
user_removed_chars: 0,
});
});
@@ -83,8 +103,12 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 0,
model_added_chars: 5,
model_removed_chars: 0,
user_added_lines: 0,
user_removed_lines: 1,
user_added_chars: 0,
user_removed_chars: 5,
});
});
@@ -96,12 +120,16 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 0,
model_added_chars: 5,
model_removed_chars: 0,
user_added_lines: 1,
user_removed_lines: 1,
user_added_chars: 10,
user_removed_chars: 5,
});
});
it('should handle complex changes from both AI and user', () => {
it('should handle complex changes from both model and user', () => {
const oldStr = 'line1\nline2\nline3\nline4\n';
const aiStr = 'line_one\nline2\nline_three\nline4\n';
const userStr = 'line_one\nline_two\nline_three\nline4\nline5\n';
@@ -109,8 +137,12 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 2,
ai_removed_lines: 2,
model_added_chars: 18,
model_removed_chars: 10,
user_added_lines: 2,
user_removed_lines: 1,
user_added_chars: 13,
user_removed_chars: 5,
});
});
@@ -122,8 +154,12 @@ describe('getDiffStat', () => {
expect(diffStat).toEqual({
ai_added_lines: 1,
ai_removed_lines: 1,
model_added_chars: 14,
model_removed_chars: 11,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
});

View File

@@ -18,22 +18,27 @@ export function getDiffStat(
aiStr: string,
userStr: string,
): DiffStat {
const countLines = (patch: Diff.ParsedDiff) => {
let added = 0;
let removed = 0;
const getStats = (patch: Diff.ParsedDiff) => {
let addedLines = 0;
let removedLines = 0;
let addedChars = 0;
let removedChars = 0;
patch.hunks.forEach((hunk: Diff.Hunk) => {
hunk.lines.forEach((line: string) => {
if (line.startsWith('+')) {
added++;
addedLines++;
addedChars += line.length - 1;
} else if (line.startsWith('-')) {
removed++;
removedLines++;
removedChars += line.length - 1;
}
});
});
return { added, removed };
return { addedLines, removedLines, addedChars, removedChars };
};
const patch = Diff.structuredPatch(
const modelPatch = Diff.structuredPatch(
fileName,
fileName,
oldStr,
@@ -42,7 +47,7 @@ export function getDiffStat(
'Proposed',
DEFAULT_DIFF_OPTIONS,
);
const { added: aiAddedLines, removed: aiRemovedLines } = countLines(patch);
const modelStats = getStats(modelPatch);
const userPatch = Diff.structuredPatch(
fileName,
@@ -53,13 +58,16 @@ export function getDiffStat(
'User',
DEFAULT_DIFF_OPTIONS,
);
const { added: userAddedLines, removed: userRemovedLines } =
countLines(userPatch);
const userStats = getStats(userPatch);
return {
ai_added_lines: aiAddedLines,
ai_removed_lines: aiRemovedLines,
user_added_lines: userAddedLines,
user_removed_lines: userRemovedLines,
ai_added_lines: modelStats.addedLines,
ai_removed_lines: modelStats.removedLines,
model_added_chars: modelStats.addedChars,
model_removed_chars: modelStats.removedChars,
user_added_lines: userStats.addedLines,
user_removed_lines: userStats.removedLines,
user_added_chars: userStats.addedChars,
user_removed_chars: userStats.removedChars,
};
}

View File

@@ -530,8 +530,12 @@ describe('EditTool', () => {
expect((result.returnDisplay as FileDiff).diffStat).toStrictEqual({
ai_added_lines: 3,
ai_removed_lines: 3,
model_added_chars: 24,
model_removed_chars: 24,
user_added_lines: 0,
user_removed_lines: 0,
user_added_chars: 0,
user_removed_chars: 0,
});
});
@@ -591,8 +595,12 @@ describe('EditTool', () => {
expect((result.returnDisplay as FileDiff).diffStat).toStrictEqual({
ai_added_lines: 1,
ai_removed_lines: 1,
model_added_chars: 7,
model_removed_chars: 8,
user_added_lines: 1,
user_removed_lines: 1,
user_added_chars: 8,
user_removed_chars: 7,
});
});

View File

@@ -443,10 +443,14 @@ export interface FileDiff {
}
export interface DiffStat {
ai_removed_lines: number;
ai_added_lines: number;
ai_removed_lines: number;
model_added_chars: number;
model_removed_chars: number;
user_added_lines: number;
user_removed_lines: number;
user_added_chars: number;
user_removed_chars: number;
}
export interface ToolEditConfirmationDetails {