mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-25 18:46:06 +01:00
chat: avoid splitting surrogate pairs in read_file (#331005)
This commit is contained in:
@@ -22,6 +22,7 @@ import { IWorkspaceService } from '../../../platform/workspace/common/workspaceS
|
||||
import { getCachedSha256Hash } from '../../../util/common/crypto';
|
||||
import { clamp } from '../../../util/vs/base/common/numbers';
|
||||
import { dirname, extUriBiasedIgnorePathCase } from '../../../util/vs/base/common/resources';
|
||||
import { isHighSurrogate, isLowSurrogate } from '../../../util/vs/base/common/strings';
|
||||
import { sendSkillContentReadTelemetry } from '../common/skillTelemetry';
|
||||
import { URI } from '../../../util/vs/base/common/uri';
|
||||
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
|
||||
@@ -432,7 +433,11 @@ class ReadFileResult extends PromptElement<ReadFileResultProps> {
|
||||
let contents = rawContents.split('\n').map(line => {
|
||||
if (line.length > MAX_LINE_LENGTH) {
|
||||
hadLongLines = true;
|
||||
return line.slice(0, MAX_LINE_LENGTH) + ' [truncated]';
|
||||
let end = MAX_LINE_LENGTH;
|
||||
if (isHighSurrogate(line.charCodeAt(end - 1)) && isLowSurrogate(line.charCodeAt(end))) {
|
||||
end--;
|
||||
}
|
||||
return line.slice(0, end) + ' [truncated]';
|
||||
}
|
||||
return line;
|
||||
}).join('\n');
|
||||
|
||||
@@ -42,13 +42,15 @@ suite('ReadFile', () => {
|
||||
const longLine = 'x'.repeat(2500);
|
||||
const longLinesContent = `normal line\n${longLine}\nanother normal line\n${longLine}`;
|
||||
const longLinesDoc = createTextDocumentData(URI.file('/workspace/longlines.ts'), longLinesContent, 'ts').document;
|
||||
const surrogateBoundaryLine = 'x'.repeat(1999) + '\u{1F6E1}' + 'tail';
|
||||
const surrogateBoundaryDoc = createTextDocumentData(URI.file('/workspace/surrogate-boundary.ts'), surrogateBoundaryLine, 'ts').document;
|
||||
|
||||
const services = createExtensionUnitTestingServices();
|
||||
services.define(IWorkspaceService, new SyncDescriptor(
|
||||
TestWorkspaceService,
|
||||
[
|
||||
[URI.file('/workspace')],
|
||||
[testDoc, emptyDoc, whitespaceDoc, singleLineDoc, largeDoc, longLinesDoc],
|
||||
[testDoc, emptyDoc, whitespaceDoc, singleLineDoc, largeDoc, longLinesDoc, surrogateBoundaryDoc],
|
||||
]
|
||||
));
|
||||
accessor = services.createTestingAccessor();
|
||||
@@ -208,6 +210,18 @@ suite('ReadFile', () => {
|
||||
}
|
||||
});
|
||||
|
||||
test('long line truncation does not split surrogate pairs', async () => {
|
||||
const toolsService = accessor.get(IToolsService);
|
||||
const input: IReadFileParamsV2 = {
|
||||
filePath: '/workspace/surrogate-boundary.ts'
|
||||
};
|
||||
const result = await toolsService.invokeTool(ToolName.ReadFile, { input, toolInvocationToken: null as never }, CancellationToken.None);
|
||||
const resultString = await toolResultToString(accessor, result);
|
||||
const truncatedLine = resultString.split('\n').find(line => line.endsWith(' [truncated]'));
|
||||
|
||||
expect(truncatedLine).toBe('x'.repeat(1999) + ' [truncated]');
|
||||
});
|
||||
|
||||
test('read file with offset beyond file line count should throw error', async () => {
|
||||
const toolsService = accessor.get(IToolsService);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user