mirror of
https://github.com/microsoft/vscode.git
synced 2026-09-28 16:39:00 +01:00
trying new empty state! (#253689)
* exp welcome view * use exp setting * use exp setting * positioned disclaimers under title to avoid overlap * Updated chat placeholder text * some fixes * fix hygiene * make sure to add additional message * swap exp is active * add new setting --------- Co-authored-by: Elijah King <elijahwilliamking@icloud.com>
This commit is contained in:
co-authored by
Elijah King
parent
4bd42b349f
commit
73fbb0cccd
@@ -262,6 +262,12 @@ configurationRegistry.registerConfiguration({
|
||||
default: 'inline',
|
||||
tags: ['experimental', 'onExp'],
|
||||
},
|
||||
'chat.emptyChatState.enabled': {
|
||||
type: 'boolean',
|
||||
default: true,
|
||||
description: nls.localize('chat.emptyChatState', "Shows a modified empty chat state with hints in the input placeholder text."),
|
||||
tags: ['experimental', 'onExp'],
|
||||
},
|
||||
[mcpEnabledSection]: {
|
||||
type: 'boolean',
|
||||
description: nls.localize('chat.mcp.enabled', "Enables integration with Model Context Protocol servers to provide additional tools and functionality."),
|
||||
|
||||
@@ -751,12 +751,16 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
||||
const configuration = this.configurationService.inspect('workbench.secondarySideBar.defaultVisibility');
|
||||
const expIsActive = configuration.defaultValue !== 'hidden';
|
||||
|
||||
const expEmptyState = this.configurationService.getValue<boolean>('chat.emptyChatState.enabled');
|
||||
|
||||
const chatSetupTriggerContext = ContextKeyExpr.or(
|
||||
ChatContextKeys.Setup.installed.negate(),
|
||||
ChatContextKeys.Entitlement.canSignUp
|
||||
);
|
||||
|
||||
let welcomeContent: IChatViewWelcomeContent;
|
||||
const defaultAgent = this.chatAgentService.getDefaultAgent(this.location, this.input.currentModeKind);
|
||||
const additionalMessage = defaultAgent?.metadata.additionalWelcomeMessage;
|
||||
if ((startupExpValue === StartupExperimentGroup.MaximizedChat
|
||||
|| startupExpValue === StartupExperimentGroup.SplitEmptyEditorChat
|
||||
|| startupExpValue === StartupExperimentGroup.SplitWelcomeChat
|
||||
@@ -764,9 +768,10 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
||||
welcomeContent = this.getExpWelcomeViewContent();
|
||||
this.container.classList.add('experimental-welcome-view');
|
||||
}
|
||||
else if (expEmptyState) {
|
||||
welcomeContent = this.getWelcomeViewContent(additionalMessage, expEmptyState);
|
||||
}
|
||||
else {
|
||||
const defaultAgent = this.chatAgentService.getDefaultAgent(this.location, this.input.currentModeKind);
|
||||
const additionalMessage = defaultAgent?.metadata.additionalWelcomeMessage;
|
||||
const tips = this.input.currentModeKind === ChatModeKind.Ask
|
||||
? new MarkdownString(localize('chatWidget.tips', "{0} or type {1} to attach context\n\n{2} to chat with extensions\n\nType {3} to use commands", '$(attach)', '#', '$(mention)', '/'), { supportThemeIcons: true })
|
||||
: new MarkdownString(localize('chatWidget.tips.withoutParticipants', "{0} or type {1} to attach context", '$(attach)', '#'), { supportThemeIcons: true });
|
||||
@@ -790,27 +795,37 @@ export class ChatWidget extends Disposable implements IChatWidget {
|
||||
}
|
||||
}
|
||||
|
||||
private getWelcomeViewContent(additionalMessage: string | IMarkdownString | undefined): IChatViewWelcomeContent {
|
||||
const baseMessage = localize('chatMessage', "Copilot is powered by AI, so mistakes are possible. Review output carefully before use.");
|
||||
private getWelcomeViewContent(additionalMessage: string | IMarkdownString | undefined, expEmptyState?: boolean): IChatViewWelcomeContent {
|
||||
const disclaimerMessage = expEmptyState
|
||||
? localize('chatDisclaimer', "AI responses may be inaccurate.")
|
||||
: localize('chatMessage', "Copilot is powered by AI, so mistakes are possible. Review output carefully before use.");
|
||||
const icon = expEmptyState ? Codicon.chatSparkle : Codicon.copilotLarge;
|
||||
|
||||
if (this.input.currentModeKind === ChatModeKind.Ask) {
|
||||
return {
|
||||
title: localize('chatDescription', "Ask Copilot"),
|
||||
message: new MarkdownString(baseMessage),
|
||||
icon: Codicon.copilotLarge,
|
||||
title: localize('chatDescription', "Ask about your code."),
|
||||
message: new MarkdownString(disclaimerMessage),
|
||||
icon,
|
||||
additionalMessage,
|
||||
};
|
||||
} else if (this.input.currentModeKind === ChatModeKind.Edit) {
|
||||
const editsHelpMessage = localize('editsHelp', "Start your editing session by defining a set of files that you want to work with. Then ask Copilot for the changes you want to make.");
|
||||
const message = expEmptyState ? disclaimerMessage : `${editsHelpMessage}\n\n${disclaimerMessage}`;
|
||||
|
||||
return {
|
||||
title: localize('editsTitle', "Edit with Copilot"),
|
||||
message: new MarkdownString(localize('editsMessage', "Start your editing session by defining a set of files that you want to work with. Then ask Copilot for the changes you want to make.") + `\n\n${baseMessage}`),
|
||||
icon: Codicon.copilotLarge,
|
||||
title: localize('editsTitle', "Edit in context."),
|
||||
message: new MarkdownString(message),
|
||||
icon,
|
||||
additionalMessage
|
||||
};
|
||||
} else {
|
||||
const agentHelpMessage = localize('agentMessage', "Ask Copilot to edit your files in [agent mode]({0}). Copilot will automatically use multiple requests to pick files to edit, run terminal commands, and iterate on errors.", 'https://aka.ms/vscode-copilot-agent');
|
||||
const message = expEmptyState ? disclaimerMessage : `${agentHelpMessage}\n\n${disclaimerMessage}`;
|
||||
|
||||
return {
|
||||
title: localize('editsTitle', "Edit with Copilot"),
|
||||
message: new MarkdownString(localize('agentMessage', "Ask Copilot to edit your files in [agent mode]({0}). Copilot will automatically use multiple requests to pick files to edit, run terminal commands, and iterate on errors.", 'https://aka.ms/vscode-copilot-agent') + `\n\n${baseMessage}`),
|
||||
icon: Codicon.copilotLarge,
|
||||
title: localize('agentTitle', "Build with agent mode."),
|
||||
message: new MarkdownString(message),
|
||||
icon,
|
||||
additionalMessage
|
||||
};
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import { ICodeEditorService } from '../../../../../editor/browser/services/codeE
|
||||
import { Range } from '../../../../../editor/common/core/range.js';
|
||||
import { IDecorationOptions } from '../../../../../editor/common/editorCommon.js';
|
||||
import { TrackedRangeStickiness } from '../../../../../editor/common/model.js';
|
||||
import { localize } from '../../../../../nls.js';
|
||||
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
|
||||
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
|
||||
import { inputPlaceholderForeground } from '../../../../../platform/theme/common/colorRegistry.js';
|
||||
import { IThemeService } from '../../../../../platform/theme/common/themeService.js';
|
||||
@@ -18,6 +20,7 @@ import { IChatAgentCommand, IChatAgentData, IChatAgentService } from '../../comm
|
||||
import { chatSlashCommandBackground, chatSlashCommandForeground } from '../../common/chatColors.js';
|
||||
import { ChatRequestAgentPart, ChatRequestAgentSubcommandPart, ChatRequestSlashCommandPart, ChatRequestSlashPromptPart, ChatRequestTextPart, ChatRequestToolPart, ChatRequestToolSetPart, IParsedChatRequestPart, chatAgentLeader, chatSubcommandLeader } from '../../common/chatParserTypes.js';
|
||||
import { ChatRequestParser } from '../../common/chatRequestParser.js';
|
||||
import { ChatModeKind } from '../../common/constants.js';
|
||||
import { IChatWidget } from '../chat.js';
|
||||
import { ChatWidget } from '../chatWidget.js';
|
||||
import { dynamicVariableDecorationType } from './chatDynamicVariables.js';
|
||||
@@ -44,6 +47,7 @@ class InputEditorDecorations extends Disposable {
|
||||
@ICodeEditorService private readonly codeEditorService: ICodeEditorService,
|
||||
@IThemeService private readonly themeService: IThemeService,
|
||||
@IChatAgentService private readonly chatAgentService: IChatAgentService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -126,7 +130,16 @@ class InputEditorDecorations extends Disposable {
|
||||
}
|
||||
|
||||
if (!inputValue) {
|
||||
const description = this.widget.input.currentModeObs.get().description.get();
|
||||
const mode = this.widget.input.currentModeObs.get();
|
||||
let description = mode.description.get();
|
||||
if (this.configurationService.getValue<boolean>('chat.emptyChatState.enabled')) {
|
||||
if (mode.kind === ChatModeKind.Ask) {
|
||||
description += ` ${localize('askPlaceholderHint', "# context, @ extensions, / commands")}`;
|
||||
} else if (mode.kind === ChatModeKind.Edit || mode.kind === ChatModeKind.Agent) {
|
||||
description += ` ${localize('editPlaceholderHint', "# context")}`;
|
||||
}
|
||||
}
|
||||
|
||||
const decoration: IDecorationOptions[] = [
|
||||
{
|
||||
range: {
|
||||
|
||||
@@ -80,6 +80,22 @@ div.chat-welcome-view {
|
||||
}
|
||||
}
|
||||
|
||||
& > .chat-welcome-view-message.experimental-empty-state {
|
||||
position: relative;
|
||||
text-align: center;
|
||||
max-width: 100%;
|
||||
margin: 0 auto;
|
||||
color: var(--vscode-input-placeholderForeground);
|
||||
|
||||
a {
|
||||
color: var(--vscode-textLink-foreground);
|
||||
}
|
||||
p{
|
||||
margin-top: 8px;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.monaco-button {
|
||||
display: inline-block;
|
||||
width: initial;
|
||||
|
||||
@@ -20,6 +20,7 @@ import { ITelemetryService } from '../../../../../platform/telemetry/common/tele
|
||||
import { defaultButtonStyles } from '../../../../../platform/theme/browser/defaultStyles.js';
|
||||
import { ChatAgentLocation } from '../../common/constants.js';
|
||||
import { IChatWidgetService } from '../chat.js';
|
||||
import { IConfigurationService } from '../../../../../platform/configuration/common/configuration.js';
|
||||
import { chatViewsWelcomeRegistry, IChatViewsWelcomeDescriptor } from './chatViewsWelcome.js';
|
||||
|
||||
const $ = dom.$;
|
||||
@@ -142,6 +143,7 @@ export class ChatViewWelcomePart extends Disposable {
|
||||
@ILogService private logService: ILogService,
|
||||
@IChatWidgetService private chatWidgetService: IChatWidgetService,
|
||||
@ITelemetryService private telemetryService: ITelemetryService,
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
) {
|
||||
super();
|
||||
this.element = dom.$('.chat-welcome-view');
|
||||
@@ -160,13 +162,15 @@ export class ChatViewWelcomePart extends Disposable {
|
||||
title.textContent = content.title;
|
||||
|
||||
// Preview indicator
|
||||
if (typeof content.message !== 'function' && options?.isWidgetAgentWelcomeViewContent) {
|
||||
const expEmptyState = this.configurationService.getValue<boolean>('chat.emptyChatState.enabled');
|
||||
if (typeof content.message !== 'function' && options?.isWidgetAgentWelcomeViewContent && !expEmptyState) {
|
||||
const container = dom.append(this.element, $('.chat-welcome-view-indicator-container'));
|
||||
dom.append(container, $('.chat-welcome-view-subtitle', undefined, localize('agentModeSubtitle', "Agent Mode")));
|
||||
}
|
||||
|
||||
// Message
|
||||
const message = dom.append(this.element, content.isExperimental ? $('.chat-welcome-experimental-view-message') : $('.chat-welcome-view-message'));
|
||||
message.classList.toggle('experimental-empty-state', expEmptyState);
|
||||
if (typeof content.message === 'function') {
|
||||
dom.append(message, content.message(this._register(new DisposableStore())));
|
||||
} else {
|
||||
|
||||
@@ -333,9 +333,9 @@ export class BuiltinChatMode implements IChatMode {
|
||||
}
|
||||
|
||||
export namespace ChatMode {
|
||||
export const Ask = new BuiltinChatMode(ChatModeKind.Ask, 'Ask', localize('chatDescription', "Ask Copilot"));
|
||||
export const Edit = new BuiltinChatMode(ChatModeKind.Edit, 'Edit', localize('editsDescription', "Edit files in your workspace"));
|
||||
export const Agent = new BuiltinChatMode(ChatModeKind.Agent, 'Agent', localize('agentDescription', "Edit files in your workspace in agent mode"));
|
||||
export const Ask = new BuiltinChatMode(ChatModeKind.Ask, 'Ask', localize('chatDescription', "Ask a question."));
|
||||
export const Edit = new BuiltinChatMode(ChatModeKind.Edit, 'Edit', localize('editsDescription', "Edit files."));
|
||||
export const Agent = new BuiltinChatMode(ChatModeKind.Agent, 'Agent', localize('agentDescription', "Build autonomously."));
|
||||
}
|
||||
|
||||
export function isBuiltinChatMode(mode: IChatMode): boolean {
|
||||
|
||||
Reference in New Issue
Block a user