Fix question carousel reappearing after window reload (#295007)

This commit is contained in:
Copilot
2026-02-13 14:21:43 +00:00
committed by GitHub
parent a5d1c2cd44
commit d45ab2fa34
2 changed files with 56 additions and 0 deletions

View File

@@ -2311,6 +2311,17 @@ export class ChatModel extends Disposable implements IChatModel {
modelState = { value: ResponseModelState.Cancelled, completedAt: Date.now() };
}
// Mark question carousels as used after
// deserialization. After a reload, the extension is no longer listening for
// their responses, so they cannot be interacted with.
if (raw.response) {
for (const part of raw.response) {
if (hasKey(part, { kind: true }) && (part.kind === 'questionCarousel')) {
part.isUsed = true;
}
}
}
request.response = new ChatResponseModel({
responseContent: raw.response ?? [new MarkdownString(raw.response)],
session: this,

View File

@@ -167,6 +167,51 @@ suite('ChatModel', () => {
assert.strictEqual(request1.response!.shouldBeRemovedOnSend, undefined);
});
test('deserialization marks unused question carousels as used', async () => {
const serializableData: ISerializableChatData3 = {
version: 3,
sessionId: 'test-session',
creationDate: Date.now(),
customTitle: undefined,
initialLocation: ChatAgentLocation.Chat,
requests: [{
requestId: 'req1',
message: { text: 'hello', parts: [] },
variableData: { variables: [] },
response: [
{ value: 'some text', isTrusted: false },
{
kind: 'questionCarousel' as const,
questions: [{ id: 'q1', title: 'Question 1', type: 'text' as const }],
allowSkip: true,
resolveId: 'resolve1',
isUsed: false,
},
],
modelState: { value: 2 /* ResponseModelState.Cancelled */, completedAt: Date.now() },
}],
responderUsername: 'bot',
};
const model = testDisposables.add(instantiationService.createInstance(
ChatModel,
{ value: serializableData, serializer: undefined! },
{ initialLocation: ChatAgentLocation.Chat, canUseTools: true }
));
const requests = model.getRequests();
assert.strictEqual(requests.length, 1);
const response = requests[0].response!;
// The question carousel should be marked as used after deserialization
const carouselPart = response.response.value.find(p => p.kind === 'questionCarousel');
assert.ok(carouselPart);
assert.strictEqual(carouselPart.isUsed, true);
// The response should be complete (not stuck in NeedsInput)
assert.strictEqual(response.isComplete, true);
});
test('inputModel.toJSON filters extension-contributed contexts', async function () {
const model = testDisposables.add(instantiationService.createInstance(ChatModel, undefined, { initialLocation: ChatAgentLocation.Chat, canUseTools: true }));