Assorted inline chat fixes (#208769)

* fix/workaround https://github.com/microsoft/vscode/issues/208549

* fixes https://github.com/microsoft/vscode/issues/208656

* add minHeight to inline chat widget

fixes https://github.com/microsoft/vscode-copilot/issues/4770

* fixes https://github.com/microsoft/vscode/issues/208606

* only honor `refer` flag when its command is the first and only

fixes https://github.com/microsoft/vscode/issues/208574
This commit is contained in:
Johannes Rieken 2024-03-26 12:38:26 +01:00 committed by GitHub
parent 4a6ebe0ee5
commit 7a3a29fee3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 41 additions and 14 deletions

View file

@ -326,7 +326,7 @@ export class ChatInputPart extends Disposable implements IHistoryNavigationWidge
// Only allow history navigation when the input is empty. // Only allow history navigation when the input is empty.
// (If this model change happened as a result of a history navigation, this is canceled out by a call in this.navigateHistory) // (If this model change happened as a result of a history navigation, this is canceled out by a call in this.navigateHistory)
const model = this._inputEditor.getModel(); const model = this._inputEditor.getModel();
const inputHasText = !!model && model.getValueLength() > 0; const inputHasText = !!model && model.getValue().trim().length > 0;
this.inputEditorHasText.set(inputHasText); this.inputEditorHasText.set(inputHasText);
// If the user is typing on a history entry, then reset the onHistoryEntry flag so that history navigation can be disabled // If the user is typing on a history entry, then reset the onHistoryEntry flag so that history navigation can be disabled

View file

@ -20,6 +20,8 @@ import { ChatAgentLocation } from 'vs/workbench/contrib/chat/common/chatAgents';
import { editorBackground, editorForeground, inputBackground } from 'vs/platform/theme/common/colorRegistry'; import { editorBackground, editorForeground, inputBackground } from 'vs/platform/theme/common/colorRegistry';
import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel'; import { ChatModel } from 'vs/workbench/contrib/chat/common/chatModel';
import { Range } from 'vs/editor/common/core/range'; import { Range } from 'vs/editor/common/core/range';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
import { IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
export class InlineChatContentWidget implements IContentWidget { export class InlineChatContentWidget implements IContentWidget {
@ -45,11 +47,19 @@ export class InlineChatContentWidget implements IContentWidget {
constructor( constructor(
private readonly _editor: ICodeEditor, private readonly _editor: ICodeEditor,
@IInstantiationService instaService: IInstantiationService, @IInstantiationService instaService: IInstantiationService,
@IContextKeyService contextKeyService: IContextKeyService,
) { ) {
this._defaultChatModel = this._store.add(instaService.createInstance(ChatModel, `inlineChatDefaultModel/editorContentWidgetPlaceholder`, undefined)); this._defaultChatModel = this._store.add(instaService.createInstance(ChatModel, `inlineChatDefaultModel/editorContentWidgetPlaceholder`, undefined));
this._widget = instaService.createInstance( const scopedInstaService = instaService.createChild(
new ServiceCollection([
IContextKeyService,
this._store.add(contextKeyService.createScoped(this._domNode))
])
);
this._widget = scopedInstaService.createInstance(
ChatWidget, ChatWidget,
ChatAgentLocation.Editor, ChatAgentLocation.Editor,
{ resource: true }, { resource: true },

View file

@ -606,7 +606,7 @@ export class InlineChatController implements IEditorContribution {
} }
return false; return false;
}); });
if (refer && slashCommandLike) { if (refer && slashCommandLike && !this._session.lastExchange) {
this._log('[IE] seeing refer command, continuing outside editor', this._session.provider.extensionId); this._log('[IE] seeing refer command, continuing outside editor', this._session.provider.extensionId);
// cancel this request // cancel this request
@ -627,11 +627,7 @@ export class InlineChatController implements IEditorContribution {
// if agent has a refer command, massage the input to include the agent name // if agent has a refer command, massage the input to include the agent name
await this._instaService.invokeFunction(sendRequest, massagedInput); await this._instaService.invokeFunction(sendRequest, massagedInput);
if (!this._session.lastExchange) { return State.ACCEPT;
// DONE when there wasn't any exchange yet. We used the inline chat only as trampoline
return State.ACCEPT;
}
return State.WAIT_FOR_INPUT;
} }
this._session.addInput(new SessionPrompt(input, this._nextAttempt, this._nextWithIntentDetection)); this._session.addInput(new SessionPrompt(input, this._nextAttempt, this._nextWithIntentDetection));

View file

@ -54,6 +54,7 @@ import { SuggestController } from 'vs/editor/contrib/suggest/browser/suggestCont
import { IChatService } from 'vs/workbench/contrib/chat/common/chatService'; import { IChatService } from 'vs/workbench/contrib/chat/common/chatService';
import { setupCustomHover } from 'vs/base/browser/ui/hover/updatableHoverWidget'; import { setupCustomHover } from 'vs/base/browser/ui/hover/updatableHoverWidget';
import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory'; import { getDefaultHoverDelegate } from 'vs/base/browser/ui/hover/hoverDelegateFactory';
import { ServiceCollection } from 'vs/platform/instantiation/common/serviceCollection';
export interface InlineChatWidgetViewState { export interface InlineChatWidgetViewState {
@ -174,7 +175,16 @@ export class InlineChatWidget {
this._store.add(this._progressBar); this._store.add(this._progressBar);
let allowRequests = false; let allowRequests = false;
this._chatWidget = _instantiationService.createInstance(
const scopedInstaService = _instantiationService.createChild(
new ServiceCollection([
IContextKeyService,
this._store.add(_contextKeyService.createScoped(this._elements.chatWidget))
])
);
this._chatWidget = scopedInstaService.createInstance(
ChatWidget, ChatWidget,
location, location,
{ resource: true }, { resource: true },
@ -365,16 +375,24 @@ export class InlineChatWidget {
get contentHeight(): number { get contentHeight(): number {
const data = { const data = {
followUpsHeight: getTotalHeight(this._elements.followUps), followUpsHeight: getTotalHeight(this._elements.followUps),
chatWidgetHeight: this._chatWidget.contentHeight, chatWidgetContentHeight: this._chatWidget.contentHeight,
progressHeight: getTotalHeight(this._elements.progress), progressHeight: getTotalHeight(this._elements.progress),
statusHeight: getTotalHeight(this._elements.status), statusHeight: getTotalHeight(this._elements.status),
extraHeight: this._getExtraHeight() extraHeight: this._getExtraHeight()
}; };
const result = data.progressHeight + data.chatWidgetHeight + data.followUpsHeight + data.statusHeight + data.extraHeight; const result = data.progressHeight + data.chatWidgetContentHeight + data.followUpsHeight + data.statusHeight + data.extraHeight;
// console.log(`InlineChat#contentHeight ${result}`, data);
return result; return result;
} }
get minHeight(): number {
// The chat widget is variable height and supports scrolling. It
// should be at least 100px high and at most the content height.
let value = this.contentHeight;
value -= this._chatWidget.contentHeight;
value += Math.min(100, this._chatWidget.contentHeight);
return value;
}
protected _getExtraHeight(): number { protected _getExtraHeight(): number {
return 12 /* padding */ + 2 /*border*/ + 12 /*shadow*/; return 12 /* padding */ + 2 /*border*/ + 12 /*shadow*/;
} }

View file

@ -114,9 +114,8 @@ export class InlineChatZoneWidget extends ZoneWidget {
const chatContentHeight = this.widget.contentHeight; const chatContentHeight = this.widget.contentHeight;
const editorHeight = this.editor.getLayoutInfo().height; const editorHeight = this.editor.getLayoutInfo().height;
const contentHeight = Math.min(chatContentHeight, editorHeight * 0.42); const contentHeight = Math.min(chatContentHeight, Math.max(this.widget.minHeight, editorHeight * 0.42));
const heightInLines = contentHeight / this.editor.getOption(EditorOption.lineHeight); const heightInLines = contentHeight / this.editor.getOption(EditorOption.lineHeight);
// console.log('ZONE#_computeHeightInLines', { chatContentHeight, editorHeight, contentHeight, heightInLines });
return heightInLines; return heightInLines;
} }

View file

@ -7,6 +7,10 @@
z-index: 3; z-index: 3;
} }
.monaco-workbench .zone-widget.inline-chat-widget .interactive-session {
max-width: unset;
}
.monaco-workbench .zone-widget-container.inside-selection { .monaco-workbench .zone-widget-container.inside-selection {
background-color: var(--vscode-inlineChat-regionHighlight); background-color: var(--vscode-inlineChat-regionHighlight);
} }