chatWidget.ts 111,1 КБ
Newer Older
Rob Lourens's avatar
Rob Lourens включено в состав коммита
1
2
3
4
5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
6
import * as dom from '../../../../base/browser/dom.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
7
import { IMouseWheelEvent, StandardMouseEvent } from '../../../../base/browser/mouseEvent.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
8
import { Button } from '../../../../base/browser/ui/button/button.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
9
10
import { IHoverOptions } from '../../../../base/browser/ui/hover/hover.js';
import { HoverPosition } from '../../../../base/browser/ui/hover/hoverWidget.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
11
import { IListRenderer, IListVirtualDelegate } from '../../../../base/browser/ui/list/list.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
12
import { ITreeContextMenuEvent, ITreeElement } from '../../../../base/browser/ui/tree/tree.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
13
import { disposableTimeout, RunOnceScheduler, timeout } from '../../../../base/common/async.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
14
import { CancellationToken } from '../../../../base/common/cancellation.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
15
import { Codicon } from '../../../../base/common/codicons.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
16
import { fromNow, fromNowByDay } from '../../../../base/common/date.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
17
18
import { toErrorMessage } from '../../../../base/common/errorMessage.js';
import { Emitter, Event } from '../../../../base/common/event.js';
Matt Bierner's avatar
Matt Bierner включено в состав коммита
19
import { FuzzyScore } from '../../../../base/common/filters.js';
Bhavya U's avatar
Bhavya U включено в состав коммита
20
import { IMarkdownString, MarkdownString } from '../../../../base/common/htmlContent.js';
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
21
import { Iterable } from '../../../../base/common/iterator.js';
Elijah King's avatar
Elijah King включено в состав коммита
22
import { KeyCode } from '../../../../base/common/keyCodes.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
23
import { Disposable, DisposableStore, IDisposable, MutableDisposable, thenIfNotDisposed } from '../../../../base/common/lifecycle.js';
Joyce Er's avatar
Joyce Er включено в состав коммита
24
import { ResourceSet } from '../../../../base/common/map.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
25
import { Schemas } from '../../../../base/common/network.js';
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
26
import { filter } from '../../../../base/common/objects.js';
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
27
import { autorun, observableFromEvent, observableValue } from '../../../../base/common/observable.js';
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
28
import { basename, extUri, isEqual } from '../../../../base/common/resources.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
29
import { MicrotaskDelay } from '../../../../base/common/symbols.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
30
31
32
33
import { isDefined } from '../../../../base/common/types.js';
import { URI } from '../../../../base/common/uri.js';
import { ICodeEditor } from '../../../../editor/browser/editorBrowser.js';
import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
34
import { OffsetRange } from '../../../../editor/common/core/ranges/offsetRange.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
35
import { localize } from '../../../../nls.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
36
import { MenuId } from '../../../../platform/actions/common/actions.js';
Elijah King's avatar
Elijah King включено в состав коммита
37
import { ICommandService } from '../../../../platform/commands/common/commands.js';
Joyce Er's avatar
Joyce Er включено в состав коммита
38
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
João Moreno's avatar
João Moreno включено в состав коммита
39
import { ContextKeyExpr, IContextKey, IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
40
41
import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js';
import { ITextResourceEditorInput } from '../../../../platform/editor/common/editor.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
42
import { IHoverService, WorkbenchHoverDelegate } from '../../../../platform/hover/browser/hover.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
43
44
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { ServiceCollection } from '../../../../platform/instantiation/common/serviceCollection.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
45
import { WorkbenchList, WorkbenchObjectTree } from '../../../../platform/list/browser/listService.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
46
import { ILogService } from '../../../../platform/log/common/log.js';
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
47
import { bindContextKey } from '../../../../platform/observable/common/platformObservableUtils.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
48
import product from '../../../../platform/product/common/product.js';
Joyce Er's avatar
Joyce Er включено в состав коммита
49
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
50
import { buttonSecondaryBackground, buttonSecondaryForeground, buttonSecondaryHoverBackground } from '../../../../platform/theme/common/colorRegistry.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
51
import { asCssVariable } from '../../../../platform/theme/common/colorUtils.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
52
import { IThemeService } from '../../../../platform/theme/common/themeService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
53
import { IWorkspaceContextService, WorkbenchState } from '../../../../platform/workspace/common/workspace.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
54
55
import { EditorResourceAccessor } from '../../../../workbench/common/editor.js';
import { IEditorService } from '../../../../workbench/services/editor/common/editorService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
56
import { ViewContainerLocation } from '../../../common/views.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
57
import { IChatEntitlementService } from '../../../services/chat/common/chatEntitlementService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
58
import { IWorkbenchLayoutService, Position } from '../../../services/layout/browser/layoutService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
59
import { ILifecycleService } from '../../../services/lifecycle/common/lifecycle.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
60
import { IViewsService } from '../../../services/views/common/viewsService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
61
import { katexContainerClassName } from '../../markdown/common/markedKatexExtension.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
62
import { checkModeOption } from '../common/chat.js';
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
63
import { IChatAgentAttachmentCapabilities, IChatAgentCommand, IChatAgentData, IChatAgentService } from '../common/chatAgents.js';
Copilot's avatar
Copilot включено в состав коммита
64
import { ChatContextKeys } from '../common/chatContextKeys.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
65
import { applyingChatEditsFailedContextKey, decidedChatEditingResourceContextKey, hasAppliedChatEditsContextKey, hasUndecidedChatEditingResourceContextKey, IChatEditingService, IChatEditingSession, inChatEditingSessionContextKey, ModifiedFileEntryState } from '../common/chatEditingService.js';
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
66
import { IChatLayoutService } from '../common/chatLayoutService.js';
isidorn's avatar
isidorn включено в состав коммита
67
import { IChatModel, IChatResponseModel } from '../common/chatModel.js';
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
68
import { ChatMode, IChatModeService } from '../common/chatModes.js';
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
69
import { chatAgentLeader, ChatRequestAgentPart, ChatRequestDynamicVariablePart, ChatRequestSlashPromptPart, ChatRequestToolPart, ChatRequestToolSetPart, chatSubcommandLeader, formatChatQuestion, IParsedChatRequest } from '../common/chatParserTypes.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
70
import { ChatRequestParser } from '../common/chatRequestParser.js';
Bhavya U's avatar
Bhavya U включено в состав коммита
71
import { IChatLocationData, IChatSendRequestOptions, IChatService } from '../common/chatService.js';
kieferrm's avatar
kieferrm включено в состав коммита
72
import { IChatSessionsService } from '../common/chatSessionsService.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
73
import { IChatSlashCommandService } from '../common/chatSlashCommands.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
74
import { IChatTodoListService } from '../common/chatTodoListService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
75
import { ChatRequestVariableSet, IChatRequestVariableEntry, isPromptFileVariableEntry, isPromptTextVariableEntry, PromptFileVariableKind, toPromptFileVariableEntry } from '../common/chatVariableEntries.js';
Justin Chen's avatar
Justin Chen включено в состав коммита
76
import { ChatViewModel, IChatRequestViewModel, IChatResponseViewModel, isRequestVM, isResponseVM } from '../common/chatViewModel.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
77
import { IChatInputState } from '../common/chatWidgetHistoryService.js';
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
78
import { CodeBlockModelCollection } from '../common/codeBlockModelCollection.js';
Bhavya U's avatar
Bhavya U включено в состав коммита
79
import { ChatAgentLocation, ChatConfiguration, ChatModeKind } from '../common/constants.js';
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
80
import { ILanguageModelToolsService, IToolData, ToolSet } from '../common/languageModelToolsService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
81
82
import { ComputeAutomaticInstructions } from '../common/promptSyntax/computeAutomaticInstructions.js';
import { PromptsConfig } from '../common/promptSyntax/config/config.js';
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
83
import { IHandOff, PromptHeader, Target } from '../common/promptSyntax/promptFileParser.js';
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
84
import { IPromptsService } from '../common/promptSyntax/service/promptsService.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
85
import { handleModeSwitch } from './actions/chatActions.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
86
import { ChatTreeItem, ChatViewId, IChatAcceptInputOptions, IChatAccessibilityService, IChatCodeBlockInfo, IChatFileTreeInfo, IChatListItemRendererOptions, IChatWidget, IChatWidgetService, IChatWidgetViewContext, IChatWidgetViewOptions, isIChatResourceViewContext, isIChatViewViewContext } from './chat.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
87
import { ChatAccessibilityProvider } from './chatAccessibilityProvider.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
88
import { ChatAttachmentModel } from './chatAttachmentModel.js';
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
89
import { ChatSuggestNextWidget } from './chatContentParts/chatSuggestNextWidget.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
90
import { ChatInputPart, IChatInputPartOptions, IChatInputStyles } from './chatInputPart.js';
Justin Chen's avatar
Justin Chen включено в состав коммита
91
import { ChatListDelegate, ChatListItemRenderer, IChatListItemTemplate, IChatRendererDelegate } from './chatListRenderer.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
92
import { ChatEditorOptions } from './chatOptions.js';
Connor Peet's avatar
Connor Peet включено в состав коммита
93
import { ChatViewPane } from './chatViewPane.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
94
95
96
import './media/chat.css';
import './media/chatAgentHover.css';
import './media/chatViewWelcome.css';
Bhavya U's avatar
Bhavya U включено в состав коммита
97
import { ChatViewWelcomePart, IChatSuggestedPrompts, IChatViewWelcomeContent } from './viewsWelcome/chatViewWelcomeController.js';
Rob Lourens's avatar
Rob Lourens включено в состав коммита
98

Rob Lourens's avatar
Rob Lourens включено в состав коммита
99
100
const $ = dom.$;

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
101
102
103
104
105
106
const defaultChat = {
	provider: product.defaultChatAgent?.provider ?? { default: { id: '', name: '' }, enterprise: { id: '', name: '' }, apple: { id: '', name: '' }, google: { id: '', name: '' } },
	termsStatementUrl: product.defaultChatAgent?.termsStatementUrl ?? '',
	privacyStatementUrl: product.defaultChatAgent?.privacyStatementUrl ?? ''
};

Rob Lourens's avatar
Rob Lourens включено в состав коммита
107
export interface IChatViewState {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
108
	inputValue?: string;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
109
	inputState?: IChatInputState;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
110
111
}

Benjamin Christopher Simmonds's avatar
Benjamin Christopher Simmonds включено в состав коммита
112
export interface IChatWidgetStyles extends IChatInputStyles {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
113
114
115
116
	inputEditorBackground: string;
	resultEditorBackground: string;
}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
117
118
export interface IChatWidgetContrib extends IDisposable {
	readonly id: string;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
119
120
121
122

	/**
	 * A piece of state which is related to the input editor of the chat widget
	 */
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
123
	getInputState?(): IChatInputState;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
124
125
126
127

	/**
	 * Called with the result of getInputState when navigating input history.
	 */
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
128
	setInputState?(s: IChatInputState): void;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
129
130
}

Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
131
132
133
134
135
interface IChatRequestInputOptions {
	input: string;
	attachedContext: ChatRequestVariableSet;
}

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
136
137
138
139
140
export interface IChatWidgetLocationOptions {
	location: ChatAgentLocation;
	resolveData?(): IChatLocationData | undefined;
}

Joyce Er's avatar
Joyce Er включено в состав коммита
141
export function isQuickChat(widget: IChatWidget): boolean {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
142
	return isIChatResourceViewContext(widget.viewContext) && Boolean(widget.viewContext.isQuickChat);
Joyce Er's avatar
Joyce Er включено в состав коммита
143
144
}

Justin Chen's avatar
Justin Chen включено в состав коммита
145
export function isInlineChat(widget: IChatWidget): boolean {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
146
	return isIChatResourceViewContext(widget.viewContext) && Boolean(widget.viewContext.isInlineChat);
Justin Chen's avatar
Justin Chen включено в состав коммита
147
148
}

Elijah King's avatar
Elijah King включено в состав коммита
149
interface IChatHistoryListItem {
Matt Bierner's avatar
Matt Bierner включено в состав коммита
150
	readonly sessionResource: URI;
Elijah King's avatar
Elijah King включено в состав коммита
151
152
153
154
155
	readonly title: string;
	readonly lastMessageDate: number;
	readonly isActive: boolean;
}

Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
type ChatHandoffClickEvent = {
	fromAgent: string;
	toAgent: string;
	hasPrompt: boolean;
	autoSend: boolean;
};

type ChatHandoffClickClassification = {
	owner: 'digitarald';
	comment: 'Event fired when a user clicks on a handoff prompt in the chat suggest-next widget';
	fromAgent: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The agent/mode the user was in before clicking the handoff' };
	toAgent: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The agent/mode specified in the handoff' };
	hasPrompt: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Whether the handoff includes a prompt' };
	autoSend: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Whether the handoff automatically submits the request' };
};

type ChatHandoffWidgetShownEvent = {
	agent: string;
	handoffCount: number;
};

type ChatHandoffWidgetShownClassification = {
	owner: 'digitarald';
	comment: 'Event fired when the suggest-next widget is shown with handoff prompts';
	agent: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The current agent/mode that has handoffs defined' };
	handoffCount: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; isMeasurement: true; comment: 'Number of handoff options shown to the user' };
};

Elijah King's avatar
Elijah King включено в состав коммита
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
class ChatHistoryListDelegate implements IListVirtualDelegate<IChatHistoryListItem> {
	getHeight(element: IChatHistoryListItem): number {
		return 22;
	}

	getTemplateId(element: IChatHistoryListItem): string {
		return 'chatHistoryItem';
	}
}

interface IChatHistoryTemplate {
	container: HTMLElement;
	title: HTMLElement;
	date: HTMLElement;
	disposables: DisposableStore;
}

copilot-swe-agent[bot]'s avatar
copilot-swe-agent[bot] включено в состав коммита
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
class ChatHistoryHoverDelegate extends WorkbenchHoverDelegate {
	constructor(
		private readonly getViewContainerLocation: () => ViewContainerLocation,
		@IWorkbenchLayoutService private readonly layoutService: IWorkbenchLayoutService,
		@IConfigurationService configurationService: IConfigurationService,
		@IHoverService hoverService: IHoverService,
	) {
		super('element', {
			instantHover: true
		}, () => this.getHoverOptions(), configurationService, hoverService);
	}

	private getHoverOptions(): Partial<IHoverOptions> {
		const sideBarPosition = this.layoutService.getSideBarPosition();
		const viewContainerLocation = this.getViewContainerLocation();

		let hoverPosition: HoverPosition;
		if (viewContainerLocation === ViewContainerLocation.Sidebar) {
			hoverPosition = sideBarPosition === Position.LEFT ? HoverPosition.RIGHT : HoverPosition.LEFT;
		} else if (viewContainerLocation === ViewContainerLocation.AuxiliaryBar) {
			hoverPosition = sideBarPosition === Position.LEFT ? HoverPosition.LEFT : HoverPosition.RIGHT;
		} else {
			hoverPosition = HoverPosition.RIGHT;
		}

		return { additionalClasses: ['chat-history-item-hover'], position: { hoverPosition, forcePosition: true } };
	}
}

Elijah King's avatar
Elijah King включено в состав коммита
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
class ChatHistoryListRenderer implements IListRenderer<IChatHistoryListItem, IChatHistoryTemplate> {
	readonly templateId = 'chatHistoryItem';

	constructor(
		private readonly onDidClickItem: (item: IChatHistoryListItem) => void,
		private readonly formatHistoryTimestamp: (timestamp: number, todayMidnightMs: number) => string,
		private readonly todayMidnightMs: number
	) { }

	renderTemplate(container: HTMLElement): IChatHistoryTemplate {
		const disposables = new DisposableStore();

		container.classList.add('chat-welcome-history-item');
		const title = dom.append(container, $('.chat-welcome-history-title'));
		const date = dom.append(container, $('.chat-welcome-history-date'));

		container.tabIndex = 0;
		container.setAttribute('role', 'button');

		return { container, title, date, disposables };
	}

	renderElement(element: IChatHistoryListItem, index: number, templateData: IChatHistoryTemplate): void {
		const { container, title, date, disposables } = templateData;

		disposables.clear();

		title.textContent = element.title;
		date.textContent = this.formatHistoryTimestamp(element.lastMessageDate, this.todayMidnightMs);
		container.setAttribute('aria-label', element.title);

		disposables.add(dom.addDisposableListener(container, dom.EventType.CLICK, () => {
			this.onDidClickItem(element);
		}));

		disposables.add(dom.addStandardDisposableListener(container, dom.EventType.KEY_DOWN, e => {
			if (e.equals(KeyCode.Enter) || e.equals(KeyCode.Space)) {
				e.preventDefault();
				e.stopPropagation();
				this.onDidClickItem(element);
			}
		}));
	}

	disposeTemplate(templateData: IChatHistoryTemplate): void {
		templateData.disposables.dispose();
	}
}

Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
279
280
281
282
283
284
285
286
287
288
const supportsAllAttachments: Required<IChatAgentAttachmentCapabilities> = {
	supportsFileAttachments: true,
	supportsToolAttachments: true,
	supportsMCPAttachments: true,
	supportsImageAttachments: true,
	supportsSearchResultAttachments: true,
	supportsInstructionAttachments: true,
	supportsSourceControlAttachments: true,
	supportsProblemAttachments: true,
	supportsSymbolAttachments: true,
Megan Rogge's avatar
Megan Rogge включено в состав коммита
289
	supportsTerminalAttachments: true,
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
290
291
};

Rob Lourens's avatar
Rob Lourens включено в состав коммита
292
export class ChatWidget extends Disposable implements IChatWidget {
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
293
	// eslint-disable-next-line @typescript-eslint/no-explicit-any
Rob Lourens's avatar
Rob Lourens включено в состав коммита
294
	public static readonly CONTRIBS: { new(...args: [IChatWidget, ...any]): IChatWidgetContrib }[] = [];
Rob Lourens's avatar
Rob Lourens включено в состав коммита
295

Rob Lourens's avatar
Rob Lourens включено в состав коммита
296
297
298
	private readonly _onDidSubmitAgent = this._register(new Emitter<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>());
	public readonly onDidSubmitAgent = this._onDidSubmitAgent.event;

Joyce Er's avatar
Joyce Er включено в состав коммита
299
300
301
	private _onDidChangeAgent = this._register(new Emitter<{ agent: IChatAgentData; slashCommand?: IChatAgentCommand }>());
	readonly onDidChangeAgent = this._onDidChangeAgent.event;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
302
303
	private _onDidFocus = this._register(new Emitter<void>());
	readonly onDidFocus = this._onDidFocus.event;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
304

Rob Lourens's avatar
Rob Lourens включено в состав коммита
305
306
307
	private _onDidChangeViewModel = this._register(new Emitter<void>());
	readonly onDidChangeViewModel = this._onDidChangeViewModel.event;

Matt Bierner's avatar
Matt Bierner включено в состав коммита
308
309
310
	private _onDidScroll = this._register(new Emitter<void>());
	readonly onDidScroll = this._onDidScroll.event;

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
311
312
313
	private _onDidAcceptInput = this._register(new Emitter<void>());
	readonly onDidAcceptInput = this._onDidAcceptInput.event;

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
314
315
	private _onDidHide = this._register(new Emitter<void>());
	readonly onDidHide = this._onDidHide.event;
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
316

Matt Bierner's avatar
Matt Bierner включено в состав коммита
317
318
319
	private _onDidShow = this._register(new Emitter<void>());
	readonly onDidShow = this._onDidShow.event;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
320
321
322
	private _onDidChangeParsedInput = this._register(new Emitter<void>());
	readonly onDidChangeParsedInput = this._onDidChangeParsedInput.event;

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
323
324
325
	private readonly _onWillMaybeChangeHeight = new Emitter<void>();
	readonly onWillMaybeChangeHeight: Event<void> = this._onWillMaybeChangeHeight.event;

Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
326
327
328
	private _onDidChangeHeight = this._register(new Emitter<number>());
	readonly onDidChangeHeight = this._onDidChangeHeight.event;

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
329
330
331
	private readonly _onDidChangeContentHeight = new Emitter<void>();
	readonly onDidChangeContentHeight: Event<void> = this._onDidChangeContentHeight.event;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
332
	private contribs: ReadonlyArray<IChatWidgetContrib> = [];
Rob Lourens's avatar
Rob Lourens включено в состав коммита
333

Matt Bierner's avatar
Matt Bierner включено в состав коммита
334
	private tree!: WorkbenchObjectTree<ChatTreeItem, FuzzyScore>;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
335
	private renderer!: ChatListItemRenderer;
Matt Bierner's avatar
Matt Bierner включено в состав коммита
336
	private readonly _codeBlockModelCollection: CodeBlockModelCollection;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
337
	private lastItem: ChatTreeItem | undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
338

Bhavya U's avatar
Bhavya U включено в состав коммита
339
340
	private readonly inputPartDisposable: MutableDisposable<ChatInputPart> = this._register(new MutableDisposable());
	private readonly inlineInputPartDisposable: MutableDisposable<ChatInputPart> = this._register(new MutableDisposable());
Simon Siefke's avatar
Simon Siefke включено в состав коммита
341
	private readonly timeoutDisposable: MutableDisposable<IDisposable> = this._register(new MutableDisposable());
Justin Chen's avatar
Justin Chen включено в состав коммита
342
343
	private inputContainer!: HTMLElement;
	private focusedInputDOM!: HTMLElement;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
344
	private editorOptions!: ChatEditorOptions;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
345

Justin Chen's avatar
Justin Chen включено в состав коммита
346
347
	private recentlyRestoredCheckpoint: boolean = false;

Justin Chen's avatar
Justin Chen включено в состав коммита
348
349
	private settingChangeCounter = 0;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
350
351
	private listContainer!: HTMLElement;
	private container!: HTMLElement;
Justin Chen's avatar
Justin Chen включено в состав коммита
352
	private historyListContainer!: HTMLElement;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
353
354
355
356
	get domNode() {
		return this.container;
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
357
	private welcomeMessageContainer!: HTMLElement;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
358
	private readonly welcomePart: MutableDisposable<ChatViewWelcomePart> = this._register(new MutableDisposable());
Simon Siefke's avatar
Simon Siefke включено в состав коммита
359
360
	private readonly welcomeContextMenuDisposable: MutableDisposable<IDisposable> = this._register(new MutableDisposable());

Justin Chen's avatar
Justin Chen включено в состав коммита
361
	private readonly historyViewStore = this._register(new DisposableStore());
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
362
	private readonly chatSuggestNextWidget: ChatSuggestNextWidget;
Justin Chen's avatar
Justin Chen включено в состав коммита
363
	private historyList: WorkbenchList<IChatHistoryListItem> | undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
364

Rob Lourens's avatar
Rob Lourens включено в состав коммита
365
	private bodyDimension: dom.Dimension | undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
366
	private visibleChangeCount = 0;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
367
	private requestInProgress: IContextKey<boolean>;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
368
	private agentInInput: IContextKey<boolean>;
Elijah King's avatar
Elijah King включено в состав коммита
369
	private inEmptyStateWithHistoryEnabledKey: IContextKey<boolean>;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
370
	private currentRequest: Promise<void> | undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
371

Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
372
373
374
375
	private _visible = false;
	public get visible() {
		return this._visible;
	}
Rob Lourens's avatar
Rob Lourens включено в состав коммита
376
377
378

	private previousTreeScrollHeight: number = 0;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
379
380
381
	/**
	 * Whether the list is scroll-locked to the bottom. Initialize to true so that we can scroll to the bottom on first render.
	 * The initial render leads to a lot of `onDidChangeTreeContentHeight` as the renderer works out the real heights of rows.
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
382
	*/
Rob Lourens's avatar
Rob Lourens включено в состав коммита
383
384
	private scrollLock = true;

Copilot's avatar
Copilot включено в состав коммита
385
386
	private _instructionFilesCheckPromise: Promise<boolean> | undefined;
	private _instructionFilesExist: boolean | undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
387

Matt Bierner's avatar
Matt Bierner включено в состав коммита
388
	private readonly viewModelDisposables = this._register(new DisposableStore());
Rob Lourens's avatar
Rob Lourens включено в состав коммита
389
	private _viewModel: ChatViewModel | undefined;
Josh Spicer's avatar
Josh Spicer включено в состав коммита
390

Bhavya U's avatar
Bhavya U включено в состав коммита
391
392
393
	// Welcome view rendering scheduler to prevent reentrant calls
	private _welcomeRenderScheduler: RunOnceScheduler;

Josh Spicer's avatar
Josh Spicer включено в состав коммита
394
	// Coding agent locking state
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
395
396
397
398
399
400
401
402
	private _lockedAgent?: {
		id: string;
		name: string;
		prefix: string;
		displayName: string;
	};
	private readonly _lockedToCodingAgentContextKey: IContextKey<boolean>;
	private readonly _agentSupportsAttachmentsContextKey: IContextKey<boolean>;
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
403
	private _attachmentCapabilities: IChatAgentAttachmentCapabilities = supportsAllAttachments;
Bhavya U's avatar
Bhavya U включено в состав коммита
404

Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
405
406
	// Cache for prompt file descriptions to avoid async calls during rendering
	private readonly promptDescriptionsCache = new Map<string, string>();
Ben Villalobos's avatar
Ben Villalobos включено в состав коммита
407
	private readonly promptUriCache = new Map<string, URI>();
Copilot's avatar
Copilot включено в состав коммита
408
	private _isLoadingPromptDescriptions = false;
Josh Spicer's avatar
Josh Spicer включено в состав коммита
409

Megan Rogge's avatar
Megan Rogge включено в состав коммита
410
411
	private _mostRecentlyFocusedItemIndex: number = -1;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
412
	private set viewModel(viewModel: ChatViewModel | undefined) {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
413
414
415
416
417
418
419
420
421
		if (this._viewModel === viewModel) {
			return;
		}

		this.viewModelDisposables.clear();

		this._viewModel = viewModel;
		if (viewModel) {
			this.viewModelDisposables.add(viewModel);
Rob Lourens's avatar
Rob Lourens включено в состав коммита
422
423
424
			this.logService.debug('ChatWidget#setViewModel: have viewModel');
		} else {
			this.logService.debug('ChatWidget#setViewModel: no viewModel');
Rob Lourens's avatar
Rob Lourens включено в состав коммита
425
426
427
428
429
430
431
432
433
		}

		this._onDidChangeViewModel.fire();
	}

	get viewModel() {
		return this._viewModel;
	}

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
434
	private readonly _editingSession = observableValue<IChatEditingSession | undefined>(this, undefined);
Johannes's avatar
Johannes включено в состав коммита
435

Rob Lourens's avatar
Rob Lourens включено в состав коммита
436
437
438
	private parsedChatRequest: IParsedChatRequest | undefined;
	get parsedInput() {
		if (this.parsedChatRequest === undefined) {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
439
440
441
442
			if (!this.viewModel) {
				return { text: '', parts: [] };
			}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
443
			this.parsedChatRequest = this.instantiationService.createInstance(ChatRequestParser)
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
444
				.parseChatRequest(this.viewModel.sessionResource, this.getInput(), this.location, {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
445
446
					selectedAgent: this._lastSelectedAgent,
					mode: this.input.currentModeKind,
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
447
					forcedAgent: this._lockedAgent?.id ? this.chatAgentService.getAgent(this._lockedAgent.id) : undefined
Rob Lourens's avatar
Rob Lourens включено в состав коммита
448
				});
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
449
			this._onDidChangeParsedInput.fire();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
450
451
452
453
454
		}

		return this.parsedChatRequest;
	}

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
455
456
457
458
	get scopedContextKeyService(): IContextKeyService {
		return this.contextKeyService;
	}

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
459
460
461
462
463
	private readonly _location: IChatWidgetLocationOptions;
	get location() {
		return this._location.location;
	}

Joyce Er's avatar
Joyce Er включено в состав коммита
464
465
	readonly viewContext: IChatWidgetViewContext;

Rob Lourens's avatar
Rob Lourens включено в состав коммита
466
467
	get supportsChangingModes(): boolean {
		return !!this.viewOptions.supportsChangingModes;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
468
469
	}

Josh Spicer's avatar
Josh Spicer включено в состав коммита
470
471
472
473
	get chatDisclaimer(): string {
		return localize('chatDisclaimer', "AI responses may be inaccurate.");
	}

Connor Peet's avatar
Connor Peet включено в состав коммита
474
475
476
477
	get locationData() {
		return this._location.resolveData?.();
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
478
	constructor(
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
479
		location: ChatAgentLocation | IChatWidgetLocationOptions,
Joyce Er's avatar
Joyce Er включено в состав коммита
480
		_viewContext: IChatWidgetViewContext | undefined,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
481
		private readonly viewOptions: IChatWidgetViewOptions,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
482
		private readonly styles: IChatWidgetStyles,
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
483
		@ICodeEditorService private readonly codeEditorService: ICodeEditorService,
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
484
		@IEditorService private readonly editorService: IEditorService,
Joyce Er's avatar
Joyce Er включено в состав коммита
485
		@IConfigurationService private readonly configurationService: IConfigurationService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
486
487
		@IContextKeyService private readonly contextKeyService: IContextKeyService,
		@IInstantiationService private readonly instantiationService: IInstantiationService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
488
		@IChatService private readonly chatService: IChatService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
489
		@IChatAgentService private readonly chatAgentService: IChatAgentService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
490
		@IChatWidgetService private readonly chatWidgetService: IChatWidgetService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
491
		@IContextMenuService private readonly contextMenuService: IContextMenuService,
Rob Lourens's avatar
Rob Lourens включено в состав коммита
492
493
494
495
		@IChatAccessibilityService private readonly chatAccessibilityService: IChatAccessibilityService,
		@ILogService private readonly logService: ILogService,
		@IThemeService private readonly themeService: IThemeService,
		@IChatSlashCommandService private readonly chatSlashCommandService: IChatSlashCommandService,
Joyce Er's avatar
Joyce Er включено в состав коммита
496
		@IChatEditingService chatEditingService: IChatEditingService,
Joyce Er's avatar
Joyce Er включено в состав коммита
497
		@ITelemetryService private readonly telemetryService: ITelemetryService,
Martin Aeschlimann's avatar
Martin Aeschlimann включено в состав коммита
498
		@IPromptsService private readonly promptsService: IPromptsService,
Oleg Solomko's avatar
Oleg Solomko включено в состав коммита
499
		@ILanguageModelToolsService private readonly toolsService: ILanguageModelToolsService,
Elijah King's avatar
Elijah King включено в состав коммита
500
		@IChatModeService private readonly chatModeService: IChatModeService,
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
501
502
		@IChatLayoutService private readonly chatLayoutService: IChatLayoutService,
		@IChatEntitlementService private readonly chatEntitlementService: IChatEntitlementService,
Elijah King's avatar
Elijah King включено в состав коммита
503
		@ICommandService private readonly commandService: ICommandService,
Elijah King's avatar
Elijah King включено в состав коммита
504
		@IHoverService private readonly hoverService: IHoverService,
kieferrm's avatar
kieferrm включено в состав коммита
505
		@IChatSessionsService private readonly chatSessionsService: IChatSessionsService,
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
506
507
		@IChatTodoListService private readonly chatTodoListService: IChatTodoListService,
		@IWorkspaceContextService private readonly contextService: IWorkspaceContextService,
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
508
		@ILifecycleService private readonly lifecycleService: ILifecycleService
Rob Lourens's avatar
Rob Lourens включено в состав коммита
509
510
	) {
		super();
Josh Spicer's avatar
Josh Spicer включено в состав коммита
511
		this._lockedToCodingAgentContextKey = ChatContextKeys.lockedToCodingAgent.bindTo(this.contextKeyService);
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
512
		this._agentSupportsAttachmentsContextKey = ChatContextKeys.agentSupportsAttachments.bindTo(this.contextKeyService);
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
513

Joyce Er's avatar
Joyce Er включено в состав коммита
514
515
		this.viewContext = _viewContext ?? {};

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
516
517
		const viewModelObs = observableFromEvent(this, this.onDidChangeViewModel, () => this.viewModel);

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
518
519
520
521
522
523
		if (typeof location === 'object') {
			this._location = location;
		} else {
			this._location = { location };
		}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
524
525
526
527
528
		ChatContextKeys.inChatSession.bindTo(contextKeyService).set(true);
		ChatContextKeys.location.bindTo(contextKeyService).set(this._location.location);
		ChatContextKeys.inQuickChat.bindTo(contextKeyService).set(isQuickChat(this));
		this.agentInInput = ChatContextKeys.inputHasAgent.bindTo(contextKeyService);
		this.requestInProgress = ChatContextKeys.requestInProgress.bindTo(contextKeyService);
Rob Lourens's avatar
Rob Lourens включено в состав коммита
529

Elijah King's avatar
Elijah King включено в состав коммита
530
531
		// Context key for when empty state history is enabled and in empty state
		this.inEmptyStateWithHistoryEnabledKey = ChatContextKeys.inEmptyStateWithHistoryEnabled.bindTo(contextKeyService);
Bhavya U's avatar
Bhavya U включено в состав коммита
532
		this._welcomeRenderScheduler = this._register(new RunOnceScheduler(() => this.renderWelcomeViewContentIfNeeded(), 0));
Elijah King's avatar
Elijah King включено в состав коммита
533
534
535
		this._register(this.configurationService.onDidChangeConfiguration(e => {
			if (e.affectsConfiguration(ChatConfiguration.EmptyStateHistoryEnabled)) {
				this.updateEmptyStateWithHistoryContext();
Bhavya U's avatar
Bhavya U включено в состав коммита
536
				this._welcomeRenderScheduler.schedule();
Elijah King's avatar
Elijah King включено в состав коммита
537
538
539
540
			}
		}));
		this.updateEmptyStateWithHistoryContext();

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
541
		// Update welcome view content when `anonymous` condition changes
Bhavya U's avatar
Bhavya U включено в состав коммита
542
		this._register(this.chatEntitlementService.onDidChangeAnonymous(() => this._welcomeRenderScheduler.schedule()));
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
543

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
544
545
546
547
548
549
		this._register(bindContextKey(decidedChatEditingResourceContextKey, contextKeyService, (reader) => {
			const currentSession = this._editingSession.read(reader);
			if (!currentSession) {
				return;
			}
			const entries = currentSession.entries.read(reader);
Johannes's avatar
Johannes включено в состав коммита
550
			const decidedEntries = entries.filter(entry => entry.state.read(reader) !== ModifiedFileEntryState.Modified);
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
551
552
553
554
555
			return decidedEntries.map(entry => entry.entryId);
		}));
		this._register(bindContextKey(hasUndecidedChatEditingResourceContextKey, contextKeyService, (reader) => {
			const currentSession = this._editingSession.read(reader);
			const entries = currentSession?.entries.read(reader) ?? []; // using currentSession here
Johannes's avatar
Johannes включено в состав коммита
556
			const decidedEntries = entries.filter(entry => entry.state.read(reader) === ModifiedFileEntryState.Modified);
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
			return decidedEntries.length > 0;
		}));
		this._register(bindContextKey(hasAppliedChatEditsContextKey, contextKeyService, (reader) => {
			const currentSession = this._editingSession.read(reader);
			if (!currentSession) {
				return false;
			}
			const entries = currentSession.entries.read(reader);
			return entries.length > 0;
		}));
		this._register(bindContextKey(inChatEditingSessionContextKey, contextKeyService, (reader) => {
			return this._editingSession.read(reader) !== null;
		}));
		this._register(bindContextKey(ChatContextKeys.chatEditingCanUndo, contextKeyService, (r) => {
			return this._editingSession.read(r)?.canUndo.read(r) || false;
		}));
		this._register(bindContextKey(ChatContextKeys.chatEditingCanRedo, contextKeyService, (r) => {
			return this._editingSession.read(r)?.canRedo.read(r) || false;
		}));
		this._register(bindContextKey(applyingChatEditsFailedContextKey, contextKeyService, (r) => {
			const chatModel = viewModelObs.read(r)?.model;
			const editingSession = this._editingSession.read(r);
			if (!editingSession || !chatModel) {
				return false;
			}
			const lastResponse = observableFromEvent(this, chatModel.onDidChange, () => chatModel.getRequests().at(-1)?.response).read(r);
			return lastResponse?.result?.errorDetails && !lastResponse?.result?.errorDetails.responseIsIncomplete;
		}));
Matt Bierner's avatar
Matt Bierner включено в состав коммита
585

Rob Lourens's avatar
Rob Lourens включено в состав коммита
586
		this._codeBlockModelCollection = this._register(instantiationService.createInstance(CodeBlockModelCollection, undefined));
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
587
		this.chatSuggestNextWidget = this._register(this.instantiationService.createInstance(ChatSuggestNextWidget));
Alexandru Dima's avatar
Alexandru Dima включено в состав коммита
588

Joyce Er's avatar
Joyce Er включено в состав коммита
589
590
		this._register(this.configurationService.onDidChangeConfiguration((e) => {
			if (e.affectsConfiguration('chat.renderRelatedFiles')) {
Connor Peet's avatar
Connor Peet включено в состав коммита
591
				this.input.renderChatRelatedFiles();
Justin Chen's avatar
Justin Chen включено в состав коммита
592
593
594
			}

			if (e.affectsConfiguration(ChatConfiguration.EditRequests) || e.affectsConfiguration(ChatConfiguration.CheckpointsEnabled)) {
Justin Chen's avatar
Justin Chen включено в состав коммита
595
596
				this.settingChangeCounter++;
				this.onDidChangeItems();
Joyce Er's avatar
Joyce Er включено в состав коммита
597
598
			}
		}));
Johannes's avatar
Johannes включено в состав коммита
599

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
600
		this._register(autorun(r => {
Johannes's avatar
Johannes включено в состав коммита
601
602
603
604

			const viewModel = viewModelObs.read(r);
			const sessions = chatEditingService.editingSessionsObs.read(r);

Matt Bierner's avatar
Matt Bierner включено в состав коммита
605
			const session = sessions.find(candidate => isEqual(candidate.chatSessionResource, viewModel?.sessionResource));
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
606
			this._editingSession.set(undefined, undefined);
Johannes's avatar
Johannes включено в состав коммита
607
608
			this.renderChatEditingSessionState(); // this is necessary to make sure we dispose previous buttons, etc.

Johannes's avatar
Johannes включено в состав коммита
609
			if (!session) {
Johannes's avatar
Johannes включено в состав коммита
610
				// none or for a different chat widget
Johannes's avatar
Johannes включено в состав коммита
611
612
				return;
			}
Alexandru Dima's avatar
Alexandru Dima включено в состав коммита
613

614
615
616
617
			const entries = session.entries.read(r);
			for (const entry of entries) {
				entry.state.read(r); // SIGNAL
			}
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
618

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
619
			this._editingSession.set(session, undefined);
Johannes's avatar
Johannes включено в состав коммита
620

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
621
			r.store.add(session.onDidDispose(() => {
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
622
				this._editingSession.set(undefined, undefined);
Johannes's avatar
Johannes включено в состав коммита
623
				this.renderChatEditingSessionState();
Alexandru Dima's avatar
Alexandru Dima включено в состав коммита
624
			}));
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
625
			r.store.add(this.onDidChangeParsedInput(() => {
Johannes's avatar
Johannes включено в состав коммита
626
				this.renderChatEditingSessionState();
Joyce Er's avatar
Joyce Er включено в состав коммита
627
			}));
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
628
			r.store.add(this.inputEditor.onDidChangeModelContent(() => {
Joyce Er's avatar
Joyce Er включено в состав коммита
629
630
				if (this.getInput() === '') {
					this.refreshParsedInput();
Johannes's avatar
Johannes включено в состав коммита
631
					this.renderChatEditingSessionState();
Joyce Er's avatar
Joyce Er включено в состав коммита
632
633
				}
			}));
Johannes's avatar
Johannes включено в состав коммита
634
			this.renderChatEditingSessionState();
Joyce Er's avatar
Joyce Er включено в состав коммита
635
636
		}));

Matt Bierner's avatar
Matt Bierner включено в состав коммита
637
		this._register(codeEditorService.registerCodeEditorOpenHandler(async (input: ITextResourceEditorInput, _source: ICodeEditor | null, _sideBySide?: boolean): Promise<ICodeEditor | null> => {
Matt Bierner's avatar
Matt Bierner включено в состав коммита
638
			const resource = input.resource;
Matt Bierner's avatar
Matt Bierner включено в состав коммита
639
			if (resource.scheme !== Schemas.vscodeChatCodeBlock) {
Matt Bierner's avatar
Matt Bierner включено в состав коммита
640
641
642
				return null;
			}

Matt Bierner's avatar
Matt Bierner включено в состав коммита
643
			const responseId = resource.path.split('/').at(1);
Matt Bierner's avatar
Matt Bierner включено в состав коммита
644
645
646
647
648
649
650
651
652
			if (!responseId) {
				return null;
			}

			const item = this.viewModel?.getItems().find(item => item.id === responseId);
			if (!item) {
				return null;
			}

Matt Bierner's avatar
Matt Bierner включено в состав коммита
653
654
			// TODO: needs to reveal the chat view

Matt Bierner's avatar
Matt Bierner включено в состав коммита
655
656
657
658
			this.reveal(item);

			await timeout(0); // wait for list to actually render

Matt Bierner's avatar
Matt Bierner включено в состав коммита
659
660
661
662
663
664
665
666
667
668
669
670
671
			for (const codeBlockPart of this.renderer.editorsInUse()) {
				if (extUri.isEqual(codeBlockPart.uri, resource, true)) {
					const editor = codeBlockPart.editor;

					let relativeTop = 0;
					const editorDomNode = editor.getDomNode();
					if (editorDomNode) {
						const row = dom.findParentWithClass(editorDomNode, 'monaco-list-row');
						if (row) {
							relativeTop = dom.getTopLeftOffset(editorDomNode).top - dom.getTopLeftOffset(row).top;
						}
					}

Matt Bierner's avatar
Matt Bierner включено в состав коммита
672
					if (input.options?.selection) {
Matt Bierner's avatar
Matt Bierner включено в состав коммита
673
674
675
676
677
						const editorSelectionTopOffset = editor.getTopForPosition(input.options.selection.startLineNumber, input.options.selection.startColumn);
						relativeTop += editorSelectionTopOffset;

						editor.focus();
						editor.setSelection({
Matt Bierner's avatar
Matt Bierner включено в состав коммита
678
679
							startLineNumber: input.options.selection.startLineNumber,
							startColumn: input.options.selection.startColumn,
Matt Bierner's avatar
Matt Bierner включено в состав коммита
680
681
							endLineNumber: input.options.selection.endLineNumber ?? input.options.selection.startLineNumber,
							endColumn: input.options.selection.endColumn ?? input.options.selection.startColumn
Matt Bierner's avatar
Matt Bierner включено в состав коммита
682
683
						});
					}
Matt Bierner's avatar
Matt Bierner включено в состав коммита
684
685
686
687

					this.reveal(item, relativeTop);

					return editor;
Matt Bierner's avatar
Matt Bierner включено в состав коммита
688
689
690
691
				}
			}
			return null;
		}));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
692

Rob Lourens's avatar
Rob Lourens включено в состав коммита
693
		this._register(this.onDidChangeParsedInput(() => this.updateChatInputContext()));
Bhavya U's avatar
Bhavya U включено в состав коммита
694

Matt Bierner's avatar
Matt Bierner включено в состав коммита
695
696
697
		this._register(this.chatTodoListService.onDidUpdateTodos((sessionResource) => {
			if (isEqual(this.viewModel?.sessionResource, sessionResource)) {
				this.inputPart.renderChatTodoListWidget(sessionResource);
Bhavya U's avatar
Bhavya U включено в состав коммита
698
699
			}
		}));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
700
	}
Rob Lourens's avatar
Rob Lourens включено в состав коммита
701

Rob Lourens's avatar
Rob Lourens включено в состав коммита
702
703
	private _lastSelectedAgent: IChatAgentData | undefined;
	set lastSelectedAgent(agent: IChatAgentData | undefined) {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
704
		this.parsedChatRequest = undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
705
		this._lastSelectedAgent = agent;
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
706
		this._updateAgentCapabilitiesContextKeys(agent);
Rob Lourens's avatar
Rob Lourens включено в состав коммита
707
		this._onDidChangeParsedInput.fire();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
708
709
710
711
712
713
	}

	get lastSelectedAgent(): IChatAgentData | undefined {
		return this._lastSelectedAgent;
	}

Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
714
715
	private _updateAgentCapabilitiesContextKeys(agent: IChatAgentData | undefined): void {
		// Check if the agent has capabilities defined directly
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
716
		const capabilities = agent?.capabilities ?? (this._lockedAgent ? this.chatSessionsService.getCapabilitiesForSessionType(this._lockedAgent.id) : undefined);
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
717
		this._attachmentCapabilities = capabilities ?? supportsAllAttachments;
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
718

Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
719
720
		const supportsAttachments = Object.keys(filter(this._attachmentCapabilities, (key, value) => value === true)).length > 0;
		this._agentSupportsAttachmentsContextKey.set(supportsAttachments);
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
721
722
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
723
724
725
726
	get supportsFileReferences(): boolean {
		return !!this.viewOptions.supportsFileReferences;
	}

Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
727
728
	get attachmentCapabilities(): IChatAgentAttachmentCapabilities {
		return this._attachmentCapabilities;
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
729
730
	}

Johannes's avatar
Johannes включено в состав коммита
731
	get input(): ChatInputPart {
Justin Chen's avatar
Justin Chen включено в состав коммита
732
		return this.viewModel?.editing && this.configurationService.getValue<string>('chat.editRequests') !== 'input' ? this.inlineInputPart : this.inputPart;
Johannes's avatar
Johannes включено в состав коммита
733
734
	}

Bhavya U's avatar
Bhavya U включено в состав коммита
735
736
737
738
739
740
741
742
	private get inputPart(): ChatInputPart {
		return this.inputPartDisposable.value!;
	}

	private get inlineInputPart(): ChatInputPart {
		return this.inlineInputPartDisposable.value!;
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
743
	get inputEditor(): ICodeEditor {
Justin Chen's avatar
Justin Chen включено в состав коммита
744
		return this.input.inputEditor;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
745
746
	}

Johannes's avatar
Johannes включено в состав коммита
747
	get contentHeight(): number {
Bhavya U's avatar
Bhavya U включено в состав коммита
748
		return this.input.contentHeight + this.tree.contentHeight + this.chatSuggestNextWidget.height;
Johannes's avatar
Johannes включено в состав коммита
749
750
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
751
	get attachmentModel(): ChatAttachmentModel {
Justin Chen's avatar
Justin Chen включено в состав коммита
752
		return this.input.attachmentModel;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
753
754
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
755
	render(parent: HTMLElement): void {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
756
		const viewId = isIChatViewViewContext(this.viewContext) ? this.viewContext.viewId : undefined;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
757
		this.editorOptions = this._register(this.instantiationService.createInstance(ChatEditorOptions, viewId, this.styles.listForeground, this.styles.inputEditorBackground, this.styles.resultEditorBackground));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
758
		const renderInputOnTop = this.viewOptions.renderInputOnTop ?? false;
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
759
		const renderFollowups = this.viewOptions.renderFollowups ?? !renderInputOnTop;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
760
		const renderStyle = this.viewOptions.renderStyle;
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
761
		const renderInputToolbarBelowInput = this.viewOptions.renderInputToolbarBelowInput ?? false;
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
762
763

		this.container = dom.append(parent, $('.interactive-session'));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
764
		this.welcomeMessageContainer = dom.append(this.container, $('.chat-welcome-view-container', { style: 'display: none' }));
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
765
		this._register(dom.addStandardDisposableListener(this.welcomeMessageContainer, dom.EventType.CLICK, () => this.focusInput()));
Bhavya U's avatar
Bhavya U включено в состав коммита
766

Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
767
768
769
770
771
772
773
774
		this._register(this.chatSuggestNextWidget.onDidChangeHeight(() => {
			if (this.bodyDimension) {
				this.layout(this.bodyDimension.height, this.bodyDimension.width);
			}
		}));
		this._register(this.chatSuggestNextWidget.onDidSelectPrompt(({ handoff }) => {
			this.handleNextPromptSelection(handoff);
		}));
Bhavya U's avatar
Bhavya U включено в состав коммита
775

Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
776
		if (renderInputOnTop) {
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
777
			this.createInput(this.container, { renderFollowups, renderStyle, renderInputToolbarBelowInput });
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
778
779
780
			this.listContainer = dom.append(this.container, $(`.interactive-list`));
		} else {
			this.listContainer = dom.append(this.container, $(`.interactive-list`));
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
781
			dom.append(this.container, this.chatSuggestNextWidget.domNode);
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
782
			this.createInput(this.container, { renderFollowups, renderStyle, renderInputToolbarBelowInput });
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
783
784
		}

Bhavya U's avatar
Bhavya U включено в состав коммита
785
		this._welcomeRenderScheduler.schedule();
Justin Chen's avatar
Justin Chen включено в состав коммита
786
		this.createList(this.listContainer, { editable: !isInlineChat(this) && !isQuickChat(this), ...this.viewOptions.rendererOptions, renderStyle });
Rob Lourens's avatar
Rob Lourens включено в состав коммита
787

Rob Lourens's avatar
Rob Lourens включено в состав коммита
788
789
790
		const scrollDownButton = this._register(new Button(this.listContainer, {
			supportIcons: true,
			buttonBackground: asCssVariable(buttonSecondaryBackground),
Rob Lourens's avatar
Rob Lourens включено в состав коммита
791
			buttonForeground: asCssVariable(buttonSecondaryForeground),
Rob Lourens's avatar
Rob Lourens включено в состав коммита
792
793
794
795
796
797
798
			buttonHoverBackground: asCssVariable(buttonSecondaryHoverBackground),
		}));
		scrollDownButton.element.classList.add('chat-scroll-down');
		scrollDownButton.label = `$(${Codicon.chevronDown.id})`;
		scrollDownButton.setTitle(localize('scrollDownButtonLabel', "Scroll down"));
		this._register(scrollDownButton.onDidClick(() => {
			this.scrollLock = true;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
799
			this.scrollToEnd();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
800
801
		}));

Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
802
		// Update the font family and size
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
803
		this._register(autorun(reader => {
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
804
805
806
807
			const fontFamily = this.chatLayoutService.fontFamily.read(reader);
			const fontSize = this.chatLayoutService.fontSize.read(reader);

			this.container.style.setProperty('--vscode-chat-font-family', fontFamily);
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
808
			this.container.style.fontSize = `${fontSize}px`;
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
809

Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
810
			this.tree.rerender();
Ladislau Szomoru's avatar
Ladislau Szomoru включено в состав коммита
811
812
		}));

Rob Lourens's avatar
Rob Lourens включено в состав коммита
813
		this._register(this.editorOptions.onDidChange(() => this.onDidStyleChange()));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
814
815
816
817
818
		this.onDidStyleChange();

		// Do initial render
		if (this.viewModel) {
			this.onDidChangeItems();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
819
			this.scrollToEnd();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
820
		}
Rob Lourens's avatar
Rob Lourens включено в состав коммита
821

Rob Lourens's avatar
Rob Lourens включено в состав коммита
822
823
824
825
		this.contribs = ChatWidget.CONTRIBS.map(contrib => {
			try {
				return this._register(this.instantiationService.createInstance(contrib, this));
			} catch (err) {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
826
				this.logService.error('Failed to instantiate chat widget contrib', toErrorMessage(err));
Rob Lourens's avatar
Rob Lourens включено в состав коммита
827
828
829
				return undefined;
			}
		}).filter(isDefined);
Benjamin Christopher Simmonds's avatar
Benjamin Christopher Simmonds включено в состав коммита
830

Rob Lourens's avatar
Rob Lourens включено в состав коммита
831
		this._register(this.chatWidgetService.register(this));
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
832
833
834
835
836

		const parsedInput = observableFromEvent(this.onDidChangeParsedInput, () => this.parsedInput);
		this._register(autorun(r => {
			const input = parsedInput.read(r);

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
837
			const newPromptAttachments = new Map<string, IChatRequestVariableEntry>();
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
838
839
840
841
842
843
844
845
846
847
848
			const oldPromptAttachments = new Set<string>();

			// get all attachments, know those that are prompt-referenced
			for (const attachment of this.attachmentModel.attachments) {
				if (attachment.range) {
					oldPromptAttachments.add(attachment.id);
				}
			}

			// update/insert prompt-referenced attachments
			for (const part of input.parts) {
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
849
				if (part instanceof ChatRequestToolPart || part instanceof ChatRequestToolSetPart || part instanceof ChatRequestDynamicVariablePart) {
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
850
					const entry = part.toVariableEntry();
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
851
					newPromptAttachments.set(entry.id, entry);
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
852
853
854
855
					oldPromptAttachments.delete(entry.id);
				}
			}

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
856
			this.attachmentModel.updateContext(oldPromptAttachments, newPromptAttachments.values());
Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
857
		}));
Justin Chen's avatar
Justin Chen включено в состав коммита
858
859
860
861

		if (!this.focusedInputDOM) {
			this.focusedInputDOM = this.container.appendChild(dom.$('.focused-input-dom'));
		}
Rob Lourens's avatar
Rob Lourens включено в состав коммита
862
863
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
864
865
866
867
868
869
870
	private scrollToEnd() {
		if (this.lastItem) {
			const offset = Math.max(this.lastItem.currentRenderedHeight ?? 0, 1e6);
			this.tree.reveal(this.lastItem, offset);
		}
	}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
871
872
	getContrib<T extends IChatWidgetContrib>(id: string): T | undefined {
		return this.contribs.find(c => c.id === id) as T;
Rob Lourens's avatar
Rob Lourens включено в состав коммита
873
874
875
	}

	focusInput(): void {
Justin Chen's avatar
Justin Chen включено в состав коммита
876
		this.input.focus();
Alex Dima's avatar
Alex Dima включено в состав коммита
877
878
879
880
881

		// Sometimes focusing the input part is not possible,
		// but we'd like to be the last focused chat widget,
		// so we emit an optimistic onDidFocus event nonetheless.
		this._onDidFocus.fire();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
882
883
	}

Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
884
	hasInputFocus(): boolean {
Justin Chen's avatar
Justin Chen включено в состав коммита
885
		return this.input.hasFocus();
Benjamin Pasero's avatar
Benjamin Pasero включено в состав коммита
886
887
	}

Joyce Er's avatar
Joyce Er включено в состав коммита
888
	refreshParsedInput() {
Joyce Er's avatar
Joyce Er включено в состав коммита
889
890
891
		if (!this.viewModel) {
			return;
		}
Matt Bierner's avatar
Matt Bierner включено в состав коммита
892
		this.parsedChatRequest = this.instantiationService.createInstance(ChatRequestParser).parseChatRequest(this.viewModel.sessionResource, this.getInput(), this.location, { selectedAgent: this._lastSelectedAgent, mode: this.input.currentModeKind });
Joyce Er's avatar
Joyce Er включено в состав коммита
893
894
895
		this._onDidChangeParsedInput.fire();
	}

Megan Rogge's avatar
Megan Rogge включено в состав коммита
896
	getSibling(item: ChatTreeItem, type: 'next' | 'previous'): ChatTreeItem | undefined {
Matt Bierner's avatar
Matt Bierner включено в состав коммита
897
898
899
		if (!isResponseVM(item)) {
			return;
		}
meganrogge's avatar
meganrogge включено в состав коммита
900
901
902
903
904
		const items = this.viewModel?.getItems();
		if (!items) {
			return;
		}
		const responseItems = items.filter(i => isResponseVM(i));
meganrogge's avatar
meganrogge включено в состав коммита
905
		const targetIndex = responseItems.indexOf(item);
meganrogge's avatar
meganrogge включено в состав коммита
906
		if (targetIndex === undefined) {
meganrogge's avatar
meganrogge включено в состав коммита
907
908
			return;
		}
meganrogge's avatar
rename    
meganrogge включено в состав коммита
909
		const indexToFocus = type === 'next' ? targetIndex + 1 : targetIndex - 1;
meganrogge's avatar
meganrogge включено в состав коммита
910
		if (indexToFocus < 0 || indexToFocus > responseItems.length - 1) {
meganrogge's avatar
meganrogge включено в состав коммита
911
912
			return;
		}
Megan Rogge's avatar
Megan Rogge включено в состав коммита
913
		return responseItems[indexToFocus];
meganrogge's avatar
meganrogge включено в состав коммита
914
915
	}

Connor Peet's avatar
Connor Peet включено в состав коммита
916
	async clear(): Promise<void> {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
917
		this.logService.debug('ChatWidget#clear');
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
918
919
920
		if (this._dynamicMessageLayoutData) {
			this._dynamicMessageLayoutData.enabled = true;
		}
Don Jayamanne's avatar
Don Jayamanne включено в состав коммита
921
922
923
924
925
926
927
928
929
930

		if (this.viewModel) {
			this.viewModel.resetInputPlaceholder();
		}
		if (this._lockedAgent) {
			this.lockToCodingAgent(this._lockedAgent.name, this._lockedAgent.displayName, this._lockedAgent.id);
		} else {
			this.unlockFromCodingAgent();
		}

Matt Bierner's avatar
Matt Bierner включено в состав коммита
931
		this.inputPart.clearTodoListWidget(this.viewModel?.sessionResource, true);
Harald Kirschner's avatar
Harald Kirschner включено в состав коммита
932
		this.chatSuggestNextWidget.hide();
Connor Peet's avatar
Connor Peet включено в состав коммита
933
		await this.viewOptions.clear?.();
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
934
935
	}

Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
936
	private onDidChangeItems(skipDynamicLayout?: boolean) {
Elijah King's avatar
Elijah King включено в состав коммита
937
938
939
		// Update context key when items change
		this.updateEmptyStateWithHistoryContext();

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
940
		if (this._visible || !this.viewModel) {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
941
			const treeItems = (this.viewModel?.getItems() ?? [])
Matt Bierner's avatar
Matt Bierner включено в состав коммита
942
943
				.map((item): ITreeElement<ChatTreeItem> => {
					return {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
944
945
946
947
948
						element: item,
						collapsed: false,
						collapsible: false
					};
				});
Rob Lourens's avatar
Rob Lourens включено в состав коммита
949

Bhavya U's avatar
Bhavya U включено в состав коммита
950

Bhavya U's avatar
Bhavya U включено в состав коммита
951
952
953
954
955
			if (treeItems.length > 0) {
				this.updateChatViewVisibility();
			} else {
				this._welcomeRenderScheduler.schedule();
			}
Rob Lourens's avatar
Rob Lourens включено в состав коммита
956

Johannes Rieken's avatar
Johannes Rieken включено в состав коммита
957
958
			this._onWillMaybeChangeHeight.fire();

Rob Lourens's avatar
Rob Lourens включено в состав коммита
959
960
			this.lastItem = treeItems.at(-1)?.element;
			ChatContextKeys.lastItemId.bindTo(this.contextKeyService).set(this.lastItem ? [this.lastItem.id] : []);
Rob Lourens's avatar
Rob Lourens включено в состав коммита
961
962
			this.tree.setChildren(null, treeItems, {
				diffIdentityProvider: {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
963
					getId: (element) => {
Rob Lourens's avatar
Rob Lourens включено в состав коммита
964
						return element.dataId +
Rob Lourens's avatar
Rob Lourens включено в состав коммита
965
							// Ensure re-rendering an element once slash commands are loaded, so the colorization can be applied.
Rob Lourens's avatar
Rob Lourens включено в состав коммита
966
							`${(isRequestVM(element)) /* && !!this.lastSlashCommands ? '_scLoaded' : '' */}` +
Rob Lourens's avatar
Rob Lourens включено в состав коммита
967
968
							// If a response is in the process of progressive rendering, we need to ensure that it will
							// be re-rendered so progressive rendering is restarted, even if the model wasn't updated.
Rob Lourens's avatar
Rob Lourens включено в состав коммита
969
970
							`${isResponseVM(element) && element.renderData ? `_${this.visibleChangeCount}` : ''}` +
							// Re-render once content references are loaded
Joyce Er's avatar
Joyce Er включено в состав коммита
971
							(isResponseVM(element) ? `_${element.contentReferences.length}` : '') +
Joyce Er's avatar
Joyce Er включено в состав коммита
972
							// Re-render if element becomes hidden due to undo/redo
Connor Peet's avatar
Connor Peet включено в состав коммита
973
							`_${element.shouldBeRemovedOnSend ? `${element.shouldBeRemovedOnSend.afterUndoStop || '1'}` : '0'}` +
Justin Chen's avatar
Justin Chen включено в состав коммита
974
975
976
977
							// Re-render if element becomes enabled/disabled due to checkpointing
							`_${element.shouldBeBlocked ? '1' : '0'}` +
							// Re-render if we have an element currently being edited
							`_${this.viewModel?.editing ? '1' : '0'}` +
Justin Chen's avatar
Justin Chen включено в состав коммита
978
979
							// Re-render if we have an element currently being checkpointed
							`_${this.viewModel?.model.checkpoint ? '1' : '0'}` +
Justin Chen's avatar
Justin Chen включено в состав коммита
980
981
							// Re-render all if invoked by setting change
							`_setting${this.settingChangeCounter || '0'}` +
Matt Bierner's avatar
Matt Bierner включено в состав коммита
982
							// Rerender request if we got new content references in the response
Joyce Er's avatar
Joyce Er включено в состав коммита
983
							// since this may change how we render the corresponding attachments in the request
isidorn's avatar
isidorn включено в состав коммита
984
							(isRequestVM(element) && element.contentReferences ? `_${element.contentReferences?.length}` : '');
Rob Lourens's avatar
Rob Lourens включено в состав коммита
985
986
987
					},
				}
			});
Rob Lourens's avatar
Rob Lourens включено в состав коммита
988

Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
989
			if (!skipDynamicLayout && this._dynamicMessageLayoutData) {
Tyler James Leonhardt's avatar
Tyler James Leonhardt включено в состав коммита
990
991
992
				this.layoutDynamicChatTreeItemMode();
			}

Rob Lourens's avatar
Rob Lourens включено в состав коммита
993
			this.renderFollowups();
Rob Lourens's avatar
Rob Lourens включено в состав коммита
994
995
996
		}
	}

Bhavya U's avatar
Bhavya U включено в состав коммита
997
998
999
1000
	/**
	 * Updates the DOM visibility of welcome view and chat list immediately
	 * @internal
	 */
Для ускорения просмотра не вся история отображается Просмотреть всю вину