Fixes ChatResponseResource.parseUri bug

This commit is contained in:
Henning Dieterichs
2026-03-18 12:36:38 +01:00
committed by Henning Dieterichs
parent fed6799281
commit 1f4b1a7556
2 changed files with 51 additions and 2 deletions

View File

@@ -2809,7 +2809,7 @@ export namespace ChatResponseResource {
}
const parts = uri.path.split('/');
if (parts.length < 5) {
if (parts.length < 4) {
return undefined;
}

View File

@@ -25,7 +25,7 @@ import { TestExtensionService, TestStorageService } from '../../../../../test/co
import { CellUri } from '../../../../notebook/common/notebookCommon.js';
import { IChatRequestImplicitVariableEntry, IChatRequestStringVariableEntry, IChatRequestFileEntry, StringChatContextValue } from '../../../common/attachments/chatVariableEntries.js';
import { ChatAgentService, IChatAgentService } from '../../../common/participants/chatAgents.js';
import { ChatModel, ChatRequestModel, IChatRequestModeInfo, IExportableChatData, ISerializableChatData1, ISerializableChatData2, ISerializableChatData3, isExportableSessionData, isSerializableSessionData, normalizeSerializableChatData, Response } from '../../../common/model/chatModel.js';
import { ChatModel, ChatRequestModel, ChatResponseResource, IChatRequestModeInfo, IExportableChatData, ISerializableChatData1, ISerializableChatData2, ISerializableChatData3, isExportableSessionData, isSerializableSessionData, normalizeSerializableChatData, Response } from '../../../common/model/chatModel.js';
import { ChatRequestTextPart } from '../../../common/requestParser/chatParserTypes.js';
import { ChatRequestQueueKind, IChatService, IChatToolInvocation } from '../../../common/chatService/chatService.js';
import { ChatAgentLocation, ChatModeKind } from '../../../common/constants.js';
@@ -1048,3 +1048,52 @@ suite('ChatModel - Pending Requests', () => {
assert.strictEqual(pending.sendOptions.attempt, 3);
});
});
suite('ChatResponseResource', () => {
ensureNoDisposablesAreLeakedInTestSuite();
test('createUri roundtrips through parseUri without basename', () => {
const sessionResource = URI.parse('vscode-chat-session://local/session1');
const uri = ChatResponseResource.createUri(sessionResource, 'call-123', 2);
const parsed = ChatResponseResource.parseUri(uri);
assert.ok(parsed);
assert.strictEqual(parsed.sessionResource.toString(), sessionResource.toString());
assert.strictEqual(parsed.toolCallId, 'call-123');
assert.strictEqual(parsed.index, 2);
});
test('createUri roundtrips through parseUri with basename', () => {
const sessionResource = URI.parse('vscode-chat-session://local/session1');
const uri = ChatResponseResource.createUri(sessionResource, 'call-456', 0, 'file.txt');
const parsed = ChatResponseResource.parseUri(uri);
assert.ok(parsed);
assert.strictEqual(parsed.sessionResource.toString(), sessionResource.toString());
assert.strictEqual(parsed.toolCallId, 'call-456');
assert.strictEqual(parsed.index, 0);
});
test('parseUri rejects paths with fewer than 4 segments', () => {
// path "/tool/callId/0" splits into ['', 'tool', 'callId', '0'] = 4 parts => valid
// path "/tool/callId" splits into ['', 'tool', 'callId'] = 3 parts => invalid
const base = URI.from({ scheme: ChatResponseResource.scheme, authority: 'abc', path: '/tool/callId' });
assert.strictEqual(ChatResponseResource.parseUri(base), undefined);
const tooShort = URI.from({ scheme: ChatResponseResource.scheme, authority: 'abc', path: '/tool' });
assert.strictEqual(ChatResponseResource.parseUri(tooShort), undefined);
const empty = URI.from({ scheme: ChatResponseResource.scheme, authority: 'abc', path: '/' });
assert.strictEqual(ChatResponseResource.parseUri(empty), undefined);
});
test('parseUri rejects wrong scheme', () => {
const uri = URI.from({ scheme: 'file', path: '/tool/callId/0' });
assert.strictEqual(ChatResponseResource.parseUri(uri), undefined);
});
test('parseUri rejects wrong kind', () => {
const uri = URI.from({ scheme: ChatResponseResource.scheme, authority: 'abc', path: '/notTool/callId/0' });
assert.strictEqual(ChatResponseResource.parseUri(uri), undefined);
});
});