Skip to content

Commit 4ab6e5d

Browse files
authored
Properly normalize very old chat session data (microsoft#227030)
Fix microsoft/vscode-copilot#7729
1 parent 8cd1d86 commit 4ab6e5d

File tree

2 files changed

+76
-1
lines changed

2 files changed

+76
-1
lines changed

src/vs/workbench/contrib/chat/common/chatModel.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -616,6 +616,8 @@ export type ISerializableChatDataIn = ISerializableChatData1 | ISerializableChat
616616
* TODO- ChatModel#_deserialize and reviveSerializedAgent also still do some normalization and maybe that should be done in here too.
617617
*/
618618
export function normalizeSerializableChatData(raw: ISerializableChatDataIn): ISerializableChatData {
619+
normalizeOldFields(raw);
620+
619621
if (!('version' in raw)) {
620622
return {
621623
version: 3,
@@ -636,6 +638,30 @@ export function normalizeSerializableChatData(raw: ISerializableChatDataIn): ISe
636638
return raw;
637639
}
638640

641+
function normalizeOldFields(raw: ISerializableChatDataIn): void {
642+
// Fill in fields that very old chat data may be missing
643+
if (!raw.sessionId) {
644+
raw.sessionId = generateUuid();
645+
}
646+
647+
if (!raw.creationDate) {
648+
raw.creationDate = getLastYearDate();
649+
}
650+
651+
if ('version' in raw && (raw.version === 2 || raw.version === 3)) {
652+
if (!raw.lastMessageDate) {
653+
// A bug led to not porting creationDate properly, and that was copied to lastMessageDate, so fix that up if missing.
654+
raw.lastMessageDate = getLastYearDate();
655+
}
656+
}
657+
}
658+
659+
function getLastYearDate(): number {
660+
const lastYearDate = new Date();
661+
lastYearDate.setFullYear(lastYearDate.getFullYear() - 1);
662+
return lastYearDate.getTime();
663+
}
664+
639665
export function isExportableSessionData(obj: unknown): obj is IExportableChatData {
640666
const data = obj as IExportableChatData;
641667
return typeof data === 'object' &&

src/vs/workbench/contrib/chat/test/common/chatModel.test.ts

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import { MockContextKeyService } from 'vs/platform/keybinding/test/common/mockKe
1717
import { ILogService, NullLogService } from 'vs/platform/log/common/log';
1818
import { IStorageService } from 'vs/platform/storage/common/storage';
1919
import { ChatAgentLocation, ChatAgentService, IChatAgentService } from 'vs/workbench/contrib/chat/common/chatAgents';
20-
import { ChatModel, ISerializableChatData1, ISerializableChatData2, normalizeSerializableChatData, Response } from 'vs/workbench/contrib/chat/common/chatModel';
20+
import { ChatModel, ISerializableChatData1, ISerializableChatData2, ISerializableChatData3, normalizeSerializableChatData, Response } from 'vs/workbench/contrib/chat/common/chatModel';
2121
import { ChatRequestTextPart } from 'vs/workbench/contrib/chat/common/chatParserTypes';
2222
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
2323
import { TestExtensionService, TestStorageService } from 'vs/workbench/test/common/workbenchTestServices';
@@ -230,4 +230,53 @@ suite('normalizeSerializableChatData', () => {
230230
assert.strictEqual(newData.lastMessageDate, v2Data.lastMessageDate);
231231
assert.strictEqual(newData.customTitle, v2Data.computedTitle);
232232
});
233+
234+
test('old bad data', () => {
235+
const v1Data: ISerializableChatData1 = {
236+
// Testing the scenario where these are missing
237+
sessionId: undefined!,
238+
creationDate: undefined!,
239+
240+
initialLocation: undefined,
241+
isImported: false,
242+
requesterAvatarIconUri: undefined,
243+
requesterUsername: 'me',
244+
requests: [],
245+
responderAvatarIconUri: undefined,
246+
responderUsername: 'bot',
247+
welcomeMessage: []
248+
};
249+
250+
const newData = normalizeSerializableChatData(v1Data);
251+
assert.strictEqual(newData.version, 3);
252+
assert.ok(newData.creationDate > 0);
253+
assert.ok(newData.lastMessageDate > 0);
254+
assert.ok(newData.sessionId);
255+
});
256+
257+
test('v3 with bug', () => {
258+
const v3Data: ISerializableChatData3 = {
259+
// Test case where old data was wrongly normalized and these fields were missing
260+
creationDate: undefined!,
261+
lastMessageDate: undefined!,
262+
263+
version: 3,
264+
initialLocation: undefined,
265+
isImported: false,
266+
requesterAvatarIconUri: undefined,
267+
requesterUsername: 'me',
268+
requests: [],
269+
responderAvatarIconUri: undefined,
270+
responderUsername: 'bot',
271+
sessionId: 'session1',
272+
welcomeMessage: [],
273+
customTitle: 'computed title'
274+
};
275+
276+
const newData = normalizeSerializableChatData(v3Data);
277+
assert.strictEqual(newData.version, 3);
278+
assert.ok(newData.creationDate > 0);
279+
assert.ok(newData.lastMessageDate > 0);
280+
assert.ok(newData.sessionId);
281+
});
233282
});

0 commit comments

Comments
 (0)