From 845f6db25eb6da03c212a12731b893e9705adeee Mon Sep 17 00:00:00 2001 From: sharon wang Date: Tue, 24 Jun 2025 18:00:04 -0400 Subject: [PATCH 1/8] disable input and show welcome text if not signed into Chat Provider --- src/vs/workbench/contrib/chat/browser/chatWidget.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 2b949e8991dc..bf9d5fa170c9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -528,7 +528,7 @@ export class ChatWidget extends Disposable implements IChatWidget { // --- Start Positron --- // Don't show the input part if the assistant is disabled - if (!this.configurationService.getValue('positron.assistant.enable')) { + if (!this.configurationService.getValue('positron.assistant.enable') || !this.chatProvidersAuthenticated()) { const input = this.container.querySelector('.interactive-input-part') as HTMLElement; if (input) { dom.hide(input); @@ -723,6 +723,10 @@ export class ChatWidget extends Disposable implements IChatWidget { } // --- Start Positron --- + private chatProvidersAuthenticated(): boolean { + return this.languageModelsService.getLanguageModelIds().length > 0 && !!this.languageModelsService.currentProvider; + } + private renderWelcomeViewContentIfNeeded() { if (this.viewOptions.renderStyle === 'compact' || this.viewOptions.renderStyle === 'minimal') { // Pull but discard the welcome view content (to allow code from @@ -741,12 +745,12 @@ export class ChatWidget extends Disposable implements IChatWidget { if (!this.configurationService.getValue('positron.assistant.enable')) { welcomeTitle = localize('positronAssistant.comingSoonTitle', "Coming Soon"); welcomeText = localize('positronAssistant.comingSoonMessage', "Positron Assistant is under development and will be available in a future version of Positron.\n"); - } else if (this.languageModelsService.getLanguageModelIds().length === 0) { + } else if (!this.chatProvidersAuthenticated()) { welcomeTitle = localize('positronAssistant.gettingStartedTitle', "Set Up Positron Assistant"); const addLanguageModelMessage = localize('positronAssistant.addLanguageModelMessage', "Add Language Model Provider"); firstLinkToButton = true; // create a multi-line message - welcomeText = localize('positronAssistant.welcomeMessage', "To use Positron Assistant you must first select and authenticate with a language model provider.\n"); + welcomeText = localize('positronAssistant.welcomeMessage', "To use Positron Assistant you must first select and authenticate with a language model provider that supports Chat.\n"); welcomeText += `\n\n[${addLanguageModelMessage}](command:positron-assistant.configureModels)`; } else { const guideLinkMessage = localize('positronAssistant.guideLinkMessage', "Positron Assistant User Guide"); From 88d00b0a36a522222d471a2c15b132799e6da50f Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 11:28:10 -0400 Subject: [PATCH 2/8] add horizontal group component same as vertical stack but with horizontal layout --- .../components/horizontalGroup.css | 10 +++++++++ .../components/horizontalGroup.tsx | 22 +++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css create mode 100644 src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx diff --git a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css new file mode 100644 index 000000000000..3793f83f6ac5 --- /dev/null +++ b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css @@ -0,0 +1,10 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2022 Posit Software, PBC. All rights reserved. + * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. + *--------------------------------------------------------------------------------------------*/ + +.positron-modal-dialog-box .horizontal-group { + gap: 16px; + display: flex; + flex-direction: row; +} diff --git a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx new file mode 100644 index 000000000000..8be5ce8b9d3d --- /dev/null +++ b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx @@ -0,0 +1,22 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (C) 2025 Posit Software, PBC. All rights reserved. + * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. + *--------------------------------------------------------------------------------------------*/ + +// CSS. +import './horizontalGroup.css'; + +// React. +import React, { PropsWithChildren } from 'react'; + +/** + * HorizontalGroup component. + */ +export const HorizontalGroup = (props: PropsWithChildren) => { + // Render. + return ( +
+ {props.children} +
+ ); +}; From 3e6040d0363c048f3bd74c446bda44c4bf52bc01 Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 11:33:06 -0400 Subject: [PATCH 3/8] optionally pass provider types to the language model modal --- extensions/positron-assistant/package.json | 12 +++++ .../positron-assistant/package.nls.json | 2 + extensions/positron-assistant/src/config.ts | 50 ++++++++++--------- .../positron-assistant/src/extension.ts | 10 +++- src/positron-dts/positron.d.ts | 1 + .../browser/positron/mainThreadAiFeatures.ts | 4 +- .../positron/extHost.positron.api.impl.ts | 4 +- .../positron/extHost.positron.protocol.ts | 4 +- .../api/common/positron/extHostAiFeatures.ts | 5 +- .../browser/languageModelModalDialog.tsx | 3 ++ .../browser/positronAssistantService.ts | 5 +- .../interfaces/positronAssistantService.ts | 1 + 12 files changed, 67 insertions(+), 34 deletions(-) diff --git a/extensions/positron-assistant/package.json b/extensions/positron-assistant/package.json index 10db4a02bd2f..5216e7126299 100644 --- a/extensions/positron-assistant/package.json +++ b/extensions/positron-assistant/package.json @@ -111,6 +111,18 @@ "category": "%commands.category%", "enablement": "config.positron.assistant.enable" }, + { + "command": "positron-assistant.configureChatModels", + "title": "%commands.configureChatModels.title%", + "category": "%commands.category%", + "enablement": "config.positron.assistant.enable" + }, + { + "command": "positron-assistant.configureCompletionModels", + "title": "%commands.configureCompletionModels.title%", + "category": "%commands.category%", + "enablement": "config.positron.assistant.enable" + }, { "command": "positron-assistant.logStoredModels", "title": "%commands.logStoredModels.title%", diff --git a/extensions/positron-assistant/package.nls.json b/extensions/positron-assistant/package.nls.json index 91886d5d4d71..6ceda76a0d82 100644 --- a/extensions/positron-assistant/package.nls.json +++ b/extensions/positron-assistant/package.nls.json @@ -2,6 +2,8 @@ "displayName": "Positron Assistant", "description": "Provides default assistant and language models for Positron.", "commands.configureModels.title": "Configure Language Model Providers", + "commands.configureChatModels.title": "Configure Language Model Providers: Chat", + "commands.configureCompletionModels.title": "Configure Language Model Providers: Completions", "commands.logStoredModels.title": "Log the stored language models", "commands.copilot.signin.title": "Copilot Sign In", "commands.copilot.signout.title": "Copilot Sign Out", diff --git a/extensions/positron-assistant/src/config.ts b/extensions/positron-assistant/src/config.ts index 9d3773085b39..4ebaea3af37e 100644 --- a/extensions/positron-assistant/src/config.ts +++ b/extensions/positron-assistant/src/config.ts @@ -130,7 +130,7 @@ export async function getEnabledProviders(): Promise { return enabledProviders; } -export async function showConfigurationDialog(context: vscode.ExtensionContext, storage: SecretStorage) { +export async function showConfigurationDialog(context: vscode.ExtensionContext, storage: SecretStorage, providerTypes?: positron.PositronLanguageModelType[]): Promise { // Gather model sources; ignore disabled providers const enabledProviders = await getEnabledProviders(); @@ -147,28 +147,32 @@ export async function showConfigurationDialog(context: vscode.ExtensionContext, }); // Show a modal asking user for configuration details - return positron.ai.showLanguageModelConfig(sources, async (userConfig, action) => { - switch (action) { - case 'save': - await saveModel(userConfig, sources, storage, context); - break; - case 'delete': - await deleteConfigurationByProvider(context, storage, userConfig.provider); - break; - case 'oauth-signin': - await oauthSignin(userConfig, sources, storage, context); - break; - case 'oauth-signout': - await oauthSignout(userConfig, sources, storage, context); - break; - case 'cancel': - // User cancelled the dialog, clean up any pending operations - CopilotService.instance().cancelCurrentOperation(); - break; - default: - throw new Error(vscode.l10n.t('Invalid Language Model action: {0}', action)); - } - }); + return positron.ai.showLanguageModelConfig( + sources, + async (userConfig, action) => { + switch (action) { + case 'save': + await saveModel(userConfig, sources, storage, context); + break; + case 'delete': + await deleteConfigurationByProvider(context, storage, userConfig.provider); + break; + case 'oauth-signin': + await oauthSignin(userConfig, sources, storage, context); + break; + case 'oauth-signout': + await oauthSignout(userConfig, sources, storage, context); + break; + case 'cancel': + // User cancelled the dialog, clean up any pending operations + CopilotService.instance().cancelCurrentOperation(); + break; + default: + throw new Error(vscode.l10n.t('Invalid Language Model action: {0}', action)); + } + }, + providerTypes + ); } diff --git a/extensions/positron-assistant/src/extension.ts b/extensions/positron-assistant/src/extension.ts index 5bd28e97c992..be82c5e7d757 100644 --- a/extensions/positron-assistant/src/extension.ts +++ b/extensions/positron-assistant/src/extension.ts @@ -198,8 +198,14 @@ async function registerModelWithAPI(modelConfig: ModelConfig, context: vscode.Ex function registerConfigureModelsCommand(context: vscode.ExtensionContext, storage: SecretStorage) { context.subscriptions.push( - vscode.commands.registerCommand('positron-assistant.configureModels', async () => { - await showConfigurationDialog(context, storage); + vscode.commands.registerCommand('positron-assistant.configureModels', async (providerTypes?: positron.PositronLanguageModelType[]) => { + await showConfigurationDialog(context, storage, providerTypes); + }), + vscode.commands.registerCommand('positron-assistant.configureChatModels', async () => { + await showConfigurationDialog(context, storage, [positron.PositronLanguageModelType.Chat]); + }), + vscode.commands.registerCommand('positron-assistant.configureCompletionModels', async () => { + await showConfigurationDialog(context, storage, [positron.PositronLanguageModelType.Completion]); }), vscode.commands.registerCommand('positron-assistant.logStoredModels', async () => { logStoredModels(context); diff --git a/src/positron-dts/positron.d.ts b/src/positron-dts/positron.d.ts index 0585da769851..030bca14243f 100644 --- a/src/positron-dts/positron.d.ts +++ b/src/positron-dts/positron.d.ts @@ -2070,6 +2070,7 @@ declare module 'positron' { export function showLanguageModelConfig( sources: LanguageModelSource[], onAction: (config: LanguageModelConfig, action: string) => Thenable, + providerTypes?: PositronLanguageModelType[], ): Thenable; /** diff --git a/src/vs/workbench/api/browser/positron/mainThreadAiFeatures.ts b/src/vs/workbench/api/browser/positron/mainThreadAiFeatures.ts index 95fb4baa848e..ed21d2808b30 100644 --- a/src/vs/workbench/api/browser/positron/mainThreadAiFeatures.ts +++ b/src/vs/workbench/api/browser/positron/mainThreadAiFeatures.ts @@ -3,6 +3,7 @@ * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. *--------------------------------------------------------------------------------------------*/ +import { PositronLanguageModelType } from 'positron'; import { Disposable, DisposableMap } from '../../../../base/common/lifecycle.js'; import { revive } from '../../../../base/common/marshalling.js'; import { URI, UriComponents } from '../../../../base/common/uri.js'; @@ -50,7 +51,7 @@ export class MainThreadAiFeatures extends Disposable implements MainThreadAiFeat * Show a modal dialog for language model configuration. Return a promise resolving to the * configuration saved by the user. */ - $languageModelConfig(id: string, sources: IPositronLanguageModelSource[]): Thenable { + $languageModelConfig(id: string, sources: IPositronLanguageModelSource[], providerTypes?: PositronLanguageModelType[]): Thenable { return new Promise((resolve, reject) => { this._positronAssistantService.showLanguageModelModalDialog( sources, @@ -59,6 +60,7 @@ export class MainThreadAiFeatures extends Disposable implements MainThreadAiFeat resolve(); }, () => this._proxy.$onCompleteLanguageModelConfig(id), + providerTypes, ); }); } diff --git a/src/vs/workbench/api/common/positron/extHost.positron.api.impl.ts b/src/vs/workbench/api/common/positron/extHost.positron.api.impl.ts index 6dae91236c2d..2e9065300ea2 100644 --- a/src/vs/workbench/api/common/positron/extHost.positron.api.impl.ts +++ b/src/vs/workbench/api/common/positron/extHost.positron.api.impl.ts @@ -256,8 +256,8 @@ export function createPositronApiFactoryAndRegisterActors(accessor: ServicesAcce getCurrentPlotUri(): Thenable { return extHostAiFeatures.getCurrentPlotUri(); }, - showLanguageModelConfig(sources: positron.ai.LanguageModelSource[], onAction: (config: positron.ai.LanguageModelConfig, action: string) => Thenable): Thenable { - return extHostAiFeatures.showLanguageModelConfig(sources, onAction); + showLanguageModelConfig(sources: positron.ai.LanguageModelSource[], onAction: (config: positron.ai.LanguageModelConfig, action: string) => Thenable, providerTypes?: positron.PositronLanguageModelType[]): Thenable { + return extHostAiFeatures.showLanguageModelConfig(sources, onAction, providerTypes); }, registerChatAgent(agentData: positron.ai.ChatAgentData): Thenable { return extHostAiFeatures.registerChatAgent(extension, agentData); diff --git a/src/vs/workbench/api/common/positron/extHost.positron.protocol.ts b/src/vs/workbench/api/common/positron/extHost.positron.protocol.ts index c84aa3da00d3..8cdcdeb7d580 100644 --- a/src/vs/workbench/api/common/positron/extHost.positron.protocol.ts +++ b/src/vs/workbench/api/common/positron/extHost.positron.protocol.ts @@ -9,7 +9,7 @@ import { createProxyIdentifier, IRPCProtocol, SerializableObjectWithBuffers } fr import { MainContext, IWebviewPortMapping, WebviewExtensionDescription, IChatProgressDto, ExtHostQuickOpenShape } from '../extHost.protocol.js'; import { URI, UriComponents } from '../../../../base/common/uri.js'; import { IEditorContext } from '../../../services/frontendMethods/common/editorContext.js'; -import { RuntimeClientType, LanguageRuntimeSessionChannel } from './extHostTypes.positron.js'; +import { RuntimeClientType, LanguageRuntimeSessionChannel, PositronLanguageModelType } from './extHostTypes.positron.js'; import { EnvironmentVariableAction, LanguageRuntimeDynState, RuntimeSessionMetadata } from 'positron'; import { IDriverMetadata, Input } from '../../../services/positronConnections/common/interfaces/positronConnectionsDriver.js'; import { IAvailableDriverMethods } from '../../browser/positron/mainThreadConnections.js'; @@ -151,7 +151,7 @@ export interface MainThreadAiFeaturesShape { $getCurrentPlotUri(): Promise; $getPositronChatContext(request: IChatRequestData): Thenable; $responseProgress(sessionId: string, dto: IChatProgressDto): void; - $languageModelConfig(id: string, sources: IPositronLanguageModelSource[]): Thenable; + $languageModelConfig(id: string, sources: IPositronLanguageModelSource[], providerTypes?: PositronLanguageModelType[]): Thenable; $getSupportedProviders(): Thenable; $addLanguageModelConfig(source: IPositronLanguageModelSource): void; $removeLanguageModelConfig(source: IPositronLanguageModelSource): void; diff --git a/src/vs/workbench/api/common/positron/extHostAiFeatures.ts b/src/vs/workbench/api/common/positron/extHostAiFeatures.ts index e4629ae70d28..f2c3b57422ff 100644 --- a/src/vs/workbench/api/common/positron/extHostAiFeatures.ts +++ b/src/vs/workbench/api/common/positron/extHostAiFeatures.ts @@ -16,6 +16,7 @@ import { IChatRequestData, IPositronChatContext, IPositronLanguageModelConfig, I import { IExtensionDescription } from '../../../../platform/extensions/common/extensions.js'; import { generateUuid } from '../../../../base/common/uuid.js'; import { ChatAgentLocation, ChatMode } from '../../../contrib/chat/common/constants.js'; +import { PositronLanguageModelType } from './extHostTypes.positron.js'; export class ExtHostAiFeatures implements extHostProtocol.ExtHostAiFeaturesShape { @@ -46,12 +47,12 @@ export class ExtHostAiFeatures implements extHostProtocol.ExtHostAiFeaturesShape }); } - async showLanguageModelConfig(sources: positron.ai.LanguageModelSource[], onAction: (config: positron.ai.LanguageModelConfig, action: string) => Thenable): Promise { + async showLanguageModelConfig(sources: positron.ai.LanguageModelSource[], onAction: (config: positron.ai.LanguageModelConfig, action: string) => Thenable, providerTypes?: PositronLanguageModelType[]): Promise { const id = generateUuid(); this._languageModelRequestRegistry.set(id, onAction); try { - await this._proxy.$languageModelConfig(id, sources); + await this._proxy.$languageModelConfig(id, sources, providerTypes); } catch (err) { throw err; } diff --git a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx index aa73129c85e2..832edb1d0230 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx @@ -36,6 +36,7 @@ export const showLanguageModelModalDialog = ( sources: IPositronLanguageModelSource[], onAction: (config: IPositronLanguageModelConfig, action: string) => Promise, onClose: () => void, + providerTypes?: PositronLanguageModelType[], ) => { const renderer = new PositronModalReactRenderer({ keybindingService: keybindingService, @@ -51,6 +52,7 @@ export const showLanguageModelModalDialog = ( layoutService={layoutService} positronAssistantService={positronAssistantService} positronModalDialogsService={positronModalDialogsService} + providerTypes={providerTypes} renderer={renderer} sources={sources} onAction={onAction} @@ -75,6 +77,7 @@ interface LanguageModelConfigurationProps { positronAssistantService: IPositronAssistantService; positronModalDialogsService: IPositronModalDialogsService; sources: IPositronLanguageModelSource[]; + providerTypes?: PositronLanguageModelType[]; configurationService: IConfigurationService; renderer: PositronModalReactRenderer; // To find available actions, search for positron.ai.showLanguageModelConfig in extensions/positron-assistant/src/config.ts diff --git a/src/vs/workbench/contrib/positronAssistant/browser/positronAssistantService.ts b/src/vs/workbench/contrib/positronAssistant/browser/positronAssistantService.ts index 9c4a7bd2cc44..d37dd7bd25f1 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/positronAssistantService.ts +++ b/src/vs/workbench/contrib/positronAssistant/browser/positronAssistantService.ts @@ -10,7 +10,7 @@ import { IPositronPlotsService } from '../../../services/positronPlots/common/po import { IPositronVariablesService } from '../../../services/positronVariables/common/interfaces/positronVariablesService.js'; import { PositronVariablesInstance } from '../../../services/positronVariables/common/positronVariablesInstance.js'; import { ITerminalService } from '../../terminal/browser/terminal.js'; -import { IChatRequestData, IPositronAssistantService, IPositronChatContext, IPositronLanguageModelConfig, IPositronLanguageModelSource } from '../common/interfaces/positronAssistantService.js'; +import { IChatRequestData, IPositronAssistantService, IPositronChatContext, IPositronLanguageModelConfig, IPositronLanguageModelSource, PositronLanguageModelType } from '../common/interfaces/positronAssistantService.js'; import { IKeybindingService } from '../../../../platform/keybinding/common/keybinding.js'; import { ILayoutService } from '../../../../platform/layout/browser/layoutService.js'; import { showLanguageModelModalDialog } from './languageModelModalDialog.js'; @@ -233,8 +233,9 @@ export class PositronAssistantService extends Disposable implements IPositronAss sources: IPositronLanguageModelSource[], onAction: (config: IPositronLanguageModelConfig, action: string) => Promise, onClose: () => void, + providerTypes?: PositronLanguageModelType[], ): void { - showLanguageModelModalDialog(this._keybindingService, this._layoutService, this._configurationService, this, this._positronModalDialogsService, sources, onAction, onClose); + showLanguageModelModalDialog(this._keybindingService, this._layoutService, this._configurationService, this, this._positronModalDialogsService, sources, onAction, onClose, providerTypes); } getSupportedProviders(): string[] { diff --git a/src/vs/workbench/contrib/positronAssistant/common/interfaces/positronAssistantService.ts b/src/vs/workbench/contrib/positronAssistant/common/interfaces/positronAssistantService.ts index 3f064bcdc936..779c89caa355 100644 --- a/src/vs/workbench/contrib/positronAssistant/common/interfaces/positronAssistantService.ts +++ b/src/vs/workbench/contrib/positronAssistant/common/interfaces/positronAssistantService.ts @@ -115,6 +115,7 @@ export interface IPositronAssistantService { sources: IPositronLanguageModelSource[], onAction: (config: IPositronLanguageModelConfig, action: string) => Promise, onClose: () => void, + providerTypes?: PositronLanguageModelType[], ): void; /** From fbd353fe87df5f5e264ce77283ec61b972873540 Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 12:11:00 -0400 Subject: [PATCH 4/8] use dropdown filter on providers in modal --- .../contrib/chat/browser/chatWidget.ts | 2 +- .../chat/browser/positron/chatActionBar.tsx | 52 ++++++-- .../languageModelConfigComponent.tsx | 25 ---- .../browser/languageModelModalDialog.tsx | 124 ++++++++++++++++-- 4 files changed, 154 insertions(+), 49 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index bf9d5fa170c9..dac76f78800f 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -751,7 +751,7 @@ export class ChatWidget extends Disposable implements IChatWidget { firstLinkToButton = true; // create a multi-line message welcomeText = localize('positronAssistant.welcomeMessage', "To use Positron Assistant you must first select and authenticate with a language model provider that supports Chat.\n"); - welcomeText += `\n\n[${addLanguageModelMessage}](command:positron-assistant.configureModels)`; + welcomeText += `\n\n[${addLanguageModelMessage}](command:positron-assistant.configureChatModels)`; } else { const guideLinkMessage = localize('positronAssistant.guideLinkMessage', "Positron Assistant User Guide"); welcomeTitle = localize('positronAssistant.welcomeMessageTitle', "Welcome to Positron Assistant"); diff --git a/src/vs/workbench/contrib/chat/browser/positron/chatActionBar.tsx b/src/vs/workbench/contrib/chat/browser/positron/chatActionBar.tsx index 086f0efa9f7c..0dccc9f57530 100644 --- a/src/vs/workbench/contrib/chat/browser/positron/chatActionBar.tsx +++ b/src/vs/workbench/contrib/chat/browser/positron/chatActionBar.tsx @@ -19,8 +19,10 @@ interface ChatActionBarProps { onModelSelect: (newLanguageModel: IPositronChatProvider | undefined) => void; } -const addModelProviderLabel = () => localize('positronChatSelector.addModelProvider', 'Add Model Provider...'); -const addModelProviderTooltip = () => localize('positronChatSelector.addModelProviderTooltip', 'Add a Language Model Provider'); +const addChatModelProviderLabel = () => localize('positronChatSelector.addChatModelProvider', 'Add Chat Model Provider...'); +const addCompletionsModelProviderLabel = () => localize('positronChatSelector.addCompletionsModelProvider', 'Add Completions Model Provider...'); +const configureModelProvidersLabel = () => localize('positronChatSelector.configureModelProviders', 'Configure All Model Providers...'); +const addModelProviderTooltip = () => localize('positronChatSelector.addModelProviderTooltip', 'Add a Chat Model Provider'); export const ChatActionBar: React.FC = ((props) => { const positronActionBarContext = usePositronActionBarContext(); @@ -47,16 +49,38 @@ export const ChatActionBar: React.FC = ((props) => { }); }); - const otherActions = [{ - id: 'add-model-provider', - label: addModelProviderLabel(), - enabled: true, - class: undefined, - tooltip: addModelProviderTooltip(), - run: async () => { - await positronActionBarContext.commandService.executeCommand('positron-assistant.configureModels'); - } - }]; + const otherActions = [ + { + id: 'add-chat-model-provider', + label: addChatModelProviderLabel(), + enabled: true, + class: undefined, + tooltip: addModelProviderTooltip(), + run: async () => { + await positronActionBarContext.commandService.executeCommand('positron-assistant.configureChatModels'); + } + }, + { + id: 'add-completion-model-provider', + label: addCompletionsModelProviderLabel(), + enabled: true, + class: undefined, + tooltip: addModelProviderTooltip(), + run: async () => { + await positronActionBarContext.commandService.executeCommand('positron-assistant.configureCompletionModels'); + } + }, + { + id: 'configure-model-providers', + label: configureModelProvidersLabel(), + enabled: true, + class: undefined, + tooltip: addModelProviderTooltip(), + run: async () => { + await positronActionBarContext.commandService.executeCommand('positron-assistant.configureModels'); + } + }, + ]; return Separator.join(providerActions, otherActions); }, [props, providers, currentProvider, positronActionBarContext.commandService]); @@ -64,10 +88,10 @@ export const ChatActionBar: React.FC = ((props) => { const renderCurrentProvider = () => { if (!currentProvider) { return { - await positronActionBarContext.commandService.executeCommand('positron-assistant.configureModels'); + await positronActionBarContext.commandService.executeCommand('positron-assistant.configureChatModels'); }} />; } diff --git a/src/vs/workbench/contrib/positronAssistant/browser/components/languageModelConfigComponent.tsx b/src/vs/workbench/contrib/positronAssistant/browser/components/languageModelConfigComponent.tsx index 003262b968f5..7189b4141b1d 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/components/languageModelConfigComponent.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/components/languageModelConfigComponent.tsx @@ -23,7 +23,6 @@ interface LanguageModelConfigComponentProps { type IProvider = IPositronLanguageModelSource['provider']; const positEulaLabel = localize('positron.languageModelConfig.positEula', 'Posit EULA'); -const completionsOnlyEmphasizedText = localize('positron.languageModelConfig.completionsOnly', 'code completions only'); const providerTermsOfServiceLabel = localize('positron.languageModelConfig.termsOfService', 'Terms of Service'); const providerPrivacyPolicyLabel = localize('positron.languageModelConfig.privacyPolicy', 'Privacy Policy'); @@ -31,14 +30,6 @@ const apiKeyInputLabel = localize('positron.languageModelConfig.apiKeyInputLabel const signInButtonLabel = localize('positron.languageModelConfig.signIn', 'Sign in'); const signOutButtonLabel = localize('positron.languageModelConfig.signOut', 'Sign out'); -function getProviderCompletionsOnlyNoticeText(providerDisplayName: string) { - return localize( - 'positron.languageModelConfig.completionsOnlyNotice', - '{0} functions for {code-completions-only} in Positron at this time.', - providerDisplayName, - ); -} - function getProviderTermsOfServiceText(providerDisplayName: string) { return localize( 'positron.languageModelConfig.tos', @@ -81,19 +72,6 @@ function getProviderPrivacyPolicyLink(providerId: string) { } } -function getProviderCompletionsOnlyNotice(provider: IProvider) { - if (provider.id === 'copilot') { - const text = getProviderCompletionsOnlyNoticeText(provider.displayName); - return interpolate( - text, - (key) => key === 'code-completions-only' ? - {completionsOnlyEmphasizedText} : - undefined - ); - } - return undefined; -} - /** * Interpolates placeholders in a string with React nodes. * @@ -190,8 +168,6 @@ const SignInButton = (props: { authMethod: AuthMethod, authStatus: AuthStatus, o } const ProviderNotice = (props: { provider: IProvider }) => { - const completionsOnlyNotice = getProviderCompletionsOnlyNotice(props.provider); - const termsOfServiceText = getProviderTermsOfServiceText(props.provider.displayName); const termsOfService = interpolate( termsOfServiceText, @@ -220,7 +196,6 @@ const ProviderNotice = (props: { provider: IProvider }) => { const disclaimerText = getProviderUsageDisclaimerText(props.provider.displayName); return
- {completionsOnlyNotice ?

{completionsOnlyNotice}

: null}

{termsOfService}

{disclaimerText}

; diff --git a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx index 832edb1d0230..8a4398aa238e 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx @@ -26,6 +26,10 @@ import { RadioGroup } from '../../../browser/positronComponents/positronModalDia import { IDisposable } from '../../../../base/common/lifecycle.js'; import { AuthMethod, AuthStatus } from './types.js'; import { IPositronModalDialogsService } from '../../../services/positronModalDialogs/common/positronModalDialogs.js'; +// import { Checkbox } from '../../../browser/positronComponents/positronModalDialog/components/checkbox.js'; +// import { HorizontalGroup } from '../../../browser/positronComponents/positronModalDialog/components/horizontalGroup.js'; +import { DropDownListBox } from '../../../browser/positronComponents/dropDownListBox/dropDownListBox.js'; +import { DropDownListBoxItem } from '../../../browser/positronComponents/dropDownListBox/dropDownListBoxItem.js'; export const showLanguageModelModalDialog = ( keybindingService: IKeybindingService, @@ -71,6 +75,35 @@ const providerSourceToConfig = (source: IPositronLanguageModelSource): IPositron }; } +/** Dropdown entries for the provider type filter */ +const dropdownListBoxAllLabel = localize('positron.languageModelProviderModalDialog.all', "All Providers"); +const dropdownListBoxChatLabel = localize('positron.languageModelProviderModalDialog.chat', "Chat Providers"); +const dropdownListBoxCompletionLabel = localize('positron.languageModelProviderModalDialog.completion', "Completion Providers"); +const providerTypeDropdownEntries = [ + new DropDownListBoxItem({ + identifier: 'all', + title: dropdownListBoxAllLabel, + value: dropdownListBoxAllLabel, + }), + new DropDownListBoxItem({ + identifier: 'chat', + title: dropdownListBoxChatLabel, + value: dropdownListBoxChatLabel, + }), + new DropDownListBoxItem({ + identifier: 'completion', + title: dropdownListBoxCompletionLabel, + value: dropdownListBoxCompletionLabel, + }), +] + +const modalTitle = localize('positron.languageModelProviderModalDialog.providerTitle', "Configure Language Model Providers") +// const providerFilterLabel = localize('positron.languageModelProviderModalDialog.providerFilter', "Provider Filter"); +const providerLabel = localize('positron.languageModelProviderModalDialog.provider', "Provider"); +// const supportsChatLabel = localize('positron.languageModelProviderModalDialog.supportsChat', "Supports Chat"); +// const supportsCompletionsLabel = localize('positron.languageModelProviderModalDialog.supportsCompletions', "Supports Completions"); +const providerFilterDropdownTitle = localize('positron.languageModelProviderModalDialog.providerFilterDropdownTitle', "Filter Providers"); + interface LanguageModelConfigurationProps { keybindingService: IKeybindingService; layoutService: ILayoutService; @@ -88,8 +121,8 @@ interface LanguageModelConfigurationProps { const LanguageModelConfiguration = (props: React.PropsWithChildren) => { // Construct the list of providers from the sources, which are defined in the extension. See extensions/positron-assistant/src/models.ts const allProviders = props.sources; - const providers = props.sources - .filter(source => source.type === 'chat' || (source.type === 'completion' && source.provider.id === 'copilot')) + const defaultProviders = props.sources + .filter(source => source.type === PositronLanguageModelType.Chat || (source.type === PositronLanguageModelType.Completion && source.provider.id === 'copilot')) .sort((a, b) => { if (a.provider.id === 'echo' || a.provider.id === 'error') { return 1; @@ -101,7 +134,7 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren(defaultProvider); @@ -113,10 +146,40 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren(); + // Filter the sources based on the provider types, if provided. + const filteredProviders = defaultProviders.filter(source => + (props.providerTypes ? props.providerTypes.includes(source.type) : true) + ); + // List of provider sources, which is updated when the service emits a change to a language model config. // Each provider source contains the info needed to populate the modal UI with provider details, such as // the provider ID, auth methods and whether the user is signed in or not with the provider. - const [providerSources, setProviderSources] = useState(providers); + const [providerSources, setProviderSources] = useState(filteredProviders); + + // // Add state for checkboxes + // const [showChatProviders, setShowChatProviders] = useState(!props.providerTypes || props.providerTypes.includes(PositronLanguageModelType.Chat)); + // const [showCompletionProviders, setShowCompletionProviders] = useState(!props.providerTypes || props.providerTypes.includes(PositronLanguageModelType.Completion)); + + // // Update providerSources when checkboxes change + // useEffect(() => { + // const filtered = defaultProviders.filter(source => { + // if (!showChatProviders && !showCompletionProviders) { + // return true; // include all + // } + // if (showChatProviders && showCompletionProviders) { + // return source.type === PositronLanguageModelType.Chat && + // defaultProviders.some(s => s.provider.id === source.provider.id && s.type === PositronLanguageModelType.Completion); + // } + // if (showChatProviders) { + // return source.type === PositronLanguageModelType.Chat; + // } + // if (showCompletionProviders) { + // return source.type === PositronLanguageModelType.Completion; + // } + // return false; + // }); + // setProviderSources(filtered); + // }, [showChatProviders, showCompletionProviders, defaultProviders]); // Update the provider sources when the service emits a change to the language model config. // This occurs when a user signs in or out of a provider. @@ -319,19 +382,62 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren { + if (!!props.providerTypes && props.providerTypes.length === 1) { + switch (props.providerTypes[0]) { + case PositronLanguageModelType.Chat: + return 'chat'; + case PositronLanguageModelType.Completion: + return 'completion'; + default: + return 'all'; + } + } + return 'all'; + })(); + return localize('positron.languageModelModalDialog.close', "Close"))()} renderer={props.renderer} - title={(() => localize('positron.languageModelModalDialog.title', "Configure Language Model Providers"))()} + title={modalTitle} width={600} onAccept={onClose} onCancel={onClose} > - + {/* + + setShowChatProviders(checked)} + /> + setShowCompletionProviders(checked)} + /> + */} + + { + const selectedType = item.options.identifier; + if (selectedType === 'all') { + setProviderSources(defaultProviders); + } else if (selectedType === 'chat') { + setProviderSources(defaultProviders.filter(source => source.type === PositronLanguageModelType.Chat)); + } else if (selectedType === 'completion') { + setProviderSources(defaultProviders.filter(source => source.type === PositronLanguageModelType.Completion)); + } + }} + />
{ providerSources.map(source => { From ab97f96df9ad84ec2158cf44207794dc2896a1ab Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 12:12:05 -0400 Subject: [PATCH 5/8] remove horizontal group / modal checkbox approach --- .../components/horizontalGroup.css | 10 ----- .../components/horizontalGroup.tsx | 22 ---------- .../browser/languageModelModalDialog.tsx | 43 ------------------- 3 files changed, 75 deletions(-) delete mode 100644 src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css delete mode 100644 src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx diff --git a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css deleted file mode 100644 index 3793f83f6ac5..000000000000 --- a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.css +++ /dev/null @@ -1,10 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (C) 2022 Posit Software, PBC. All rights reserved. - * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. - *--------------------------------------------------------------------------------------------*/ - -.positron-modal-dialog-box .horizontal-group { - gap: 16px; - display: flex; - flex-direction: row; -} diff --git a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx b/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx deleted file mode 100644 index 8be5ce8b9d3d..000000000000 --- a/src/vs/workbench/browser/positronComponents/positronModalDialog/components/horizontalGroup.tsx +++ /dev/null @@ -1,22 +0,0 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (C) 2025 Posit Software, PBC. All rights reserved. - * Licensed under the Elastic License 2.0. See LICENSE.txt for license information. - *--------------------------------------------------------------------------------------------*/ - -// CSS. -import './horizontalGroup.css'; - -// React. -import React, { PropsWithChildren } from 'react'; - -/** - * HorizontalGroup component. - */ -export const HorizontalGroup = (props: PropsWithChildren) => { - // Render. - return ( -
- {props.children} -
- ); -}; diff --git a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx index 8a4398aa238e..77a0fdedc991 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx @@ -26,8 +26,6 @@ import { RadioGroup } from '../../../browser/positronComponents/positronModalDia import { IDisposable } from '../../../../base/common/lifecycle.js'; import { AuthMethod, AuthStatus } from './types.js'; import { IPositronModalDialogsService } from '../../../services/positronModalDialogs/common/positronModalDialogs.js'; -// import { Checkbox } from '../../../browser/positronComponents/positronModalDialog/components/checkbox.js'; -// import { HorizontalGroup } from '../../../browser/positronComponents/positronModalDialog/components/horizontalGroup.js'; import { DropDownListBox } from '../../../browser/positronComponents/dropDownListBox/dropDownListBox.js'; import { DropDownListBoxItem } from '../../../browser/positronComponents/dropDownListBox/dropDownListBoxItem.js'; @@ -98,10 +96,7 @@ const providerTypeDropdownEntries = [ ] const modalTitle = localize('positron.languageModelProviderModalDialog.providerTitle', "Configure Language Model Providers") -// const providerFilterLabel = localize('positron.languageModelProviderModalDialog.providerFilter', "Provider Filter"); const providerLabel = localize('positron.languageModelProviderModalDialog.provider', "Provider"); -// const supportsChatLabel = localize('positron.languageModelProviderModalDialog.supportsChat', "Supports Chat"); -// const supportsCompletionsLabel = localize('positron.languageModelProviderModalDialog.supportsCompletions', "Supports Completions"); const providerFilterDropdownTitle = localize('positron.languageModelProviderModalDialog.providerFilterDropdownTitle', "Filter Providers"); interface LanguageModelConfigurationProps { @@ -156,31 +151,6 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren(filteredProviders); - // // Add state for checkboxes - // const [showChatProviders, setShowChatProviders] = useState(!props.providerTypes || props.providerTypes.includes(PositronLanguageModelType.Chat)); - // const [showCompletionProviders, setShowCompletionProviders] = useState(!props.providerTypes || props.providerTypes.includes(PositronLanguageModelType.Completion)); - - // // Update providerSources when checkboxes change - // useEffect(() => { - // const filtered = defaultProviders.filter(source => { - // if (!showChatProviders && !showCompletionProviders) { - // return true; // include all - // } - // if (showChatProviders && showCompletionProviders) { - // return source.type === PositronLanguageModelType.Chat && - // defaultProviders.some(s => s.provider.id === source.provider.id && s.type === PositronLanguageModelType.Completion); - // } - // if (showChatProviders) { - // return source.type === PositronLanguageModelType.Chat; - // } - // if (showCompletionProviders) { - // return source.type === PositronLanguageModelType.Completion; - // } - // return false; - // }); - // setProviderSources(filtered); - // }, [showChatProviders, showCompletionProviders, defaultProviders]); - // Update the provider sources when the service emits a change to the language model config. // This occurs when a user signs in or out of a provider. useEffect(() => { @@ -407,19 +377,6 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren - {/* - - setShowChatProviders(checked)} - /> - setShowCompletionProviders(checked)} - /> - */} Date: Wed, 25 Jun 2025 12:17:35 -0400 Subject: [PATCH 6/8] create enum for ProviderTypeFilterOptions --- .../browser/languageModelModalDialog.tsx | 26 +++++++++---------- .../positronAssistant/browser/types.ts | 6 +++++ 2 files changed, 19 insertions(+), 13 deletions(-) diff --git a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx index 77a0fdedc991..12e58d83683e 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx @@ -24,7 +24,7 @@ import { LanguageModelConfigComponent } from './components/languageModelConfigCo import { RadioButtonItem } from '../../../browser/positronComponents/positronModalDialog/components/radioButton.js'; import { RadioGroup } from '../../../browser/positronComponents/positronModalDialog/components/radioGroup.js'; import { IDisposable } from '../../../../base/common/lifecycle.js'; -import { AuthMethod, AuthStatus } from './types.js'; +import { AuthMethod, AuthStatus, ProviderTypeFilterOptions } from './types.js'; import { IPositronModalDialogsService } from '../../../services/positronModalDialogs/common/positronModalDialogs.js'; import { DropDownListBox } from '../../../browser/positronComponents/dropDownListBox/dropDownListBox.js'; import { DropDownListBoxItem } from '../../../browser/positronComponents/dropDownListBox/dropDownListBoxItem.js'; @@ -79,17 +79,17 @@ const dropdownListBoxChatLabel = localize('positron.languageModelProviderModalDi const dropdownListBoxCompletionLabel = localize('positron.languageModelProviderModalDialog.completion', "Completion Providers"); const providerTypeDropdownEntries = [ new DropDownListBoxItem({ - identifier: 'all', + identifier: ProviderTypeFilterOptions.ALL, title: dropdownListBoxAllLabel, value: dropdownListBoxAllLabel, }), new DropDownListBoxItem({ - identifier: 'chat', + identifier: ProviderTypeFilterOptions.CHAT, title: dropdownListBoxChatLabel, value: dropdownListBoxChatLabel, }), new DropDownListBoxItem({ - identifier: 'completion', + identifier: ProviderTypeFilterOptions.COMPLETION, title: dropdownListBoxCompletionLabel, value: dropdownListBoxCompletionLabel, }), @@ -357,18 +357,18 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren localize('positron.languageModelModalDialog.close', "Close"))()} renderer={props.renderer} title={modalTitle} @@ -384,13 +384,13 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren { + onSelectionChanged={item => { const selectedType = item.options.identifier; - if (selectedType === 'all') { + if (selectedType === ProviderTypeFilterOptions.ALL) { setProviderSources(defaultProviders); - } else if (selectedType === 'chat') { + } else if (selectedType === ProviderTypeFilterOptions.CHAT) { setProviderSources(defaultProviders.filter(source => source.type === PositronLanguageModelType.Chat)); - } else if (selectedType === 'completion') { + } else if (selectedType === ProviderTypeFilterOptions.COMPLETION) { setProviderSources(defaultProviders.filter(source => source.type === PositronLanguageModelType.Completion)); } }} diff --git a/src/vs/workbench/contrib/positronAssistant/browser/types.ts b/src/vs/workbench/contrib/positronAssistant/browser/types.ts index a0a7ec7c6ffb..a413869a7e8a 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/types.ts +++ b/src/vs/workbench/contrib/positronAssistant/browser/types.ts @@ -19,3 +19,9 @@ export enum AuthStatus { /** Currently signed out */ SIGNED_OUT = 'signedOut', } + +export enum ProviderTypeFilterOptions { + ALL = 'all', + CHAT = 'chat', + COMPLETION = 'completion', +} From 6f575573e18fa872b4d9e8bd5a86fa2a29e9638b Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 12:58:20 -0400 Subject: [PATCH 7/8] fix chat input visibility logic --- .../contrib/chat/browser/chatWidget.ts | 27 ++++++++++++++----- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index dac76f78800f..aecb926eb0cf 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -528,7 +528,7 @@ export class ChatWidget extends Disposable implements IChatWidget { // --- Start Positron --- // Don't show the input part if the assistant is disabled - if (!this.configurationService.getValue('positron.assistant.enable') || !this.chatProvidersAuthenticated()) { + if (!this.configurationService.getValue('positron.assistant.enable')) { const input = this.container.querySelector('.interactive-input-part') as HTMLElement; if (input) { dom.hide(input); @@ -723,10 +723,6 @@ export class ChatWidget extends Disposable implements IChatWidget { } // --- Start Positron --- - private chatProvidersAuthenticated(): boolean { - return this.languageModelsService.getLanguageModelIds().length > 0 && !!this.languageModelsService.currentProvider; - } - private renderWelcomeViewContentIfNeeded() { if (this.viewOptions.renderStyle === 'compact' || this.viewOptions.renderStyle === 'minimal') { // Pull but discard the welcome view content (to allow code from @@ -745,13 +741,16 @@ export class ChatWidget extends Disposable implements IChatWidget { if (!this.configurationService.getValue('positron.assistant.enable')) { welcomeTitle = localize('positronAssistant.comingSoonTitle', "Coming Soon"); welcomeText = localize('positronAssistant.comingSoonMessage', "Positron Assistant is under development and will be available in a future version of Positron.\n"); - } else if (!this.chatProvidersAuthenticated()) { + } else if (!!this.languageModelsService.currentProvider) { welcomeTitle = localize('positronAssistant.gettingStartedTitle', "Set Up Positron Assistant"); const addLanguageModelMessage = localize('positronAssistant.addLanguageModelMessage', "Add Language Model Provider"); firstLinkToButton = true; // create a multi-line message welcomeText = localize('positronAssistant.welcomeMessage', "To use Positron Assistant you must first select and authenticate with a language model provider that supports Chat.\n"); welcomeText += `\n\n[${addLanguageModelMessage}](command:positron-assistant.configureChatModels)`; + + // Disable input for chat + this.toggleChatInputVisibility(false); } else { const guideLinkMessage = localize('positronAssistant.guideLinkMessage', "Positron Assistant User Guide"); welcomeTitle = localize('positronAssistant.welcomeMessageTitle', "Welcome to Positron Assistant"); @@ -769,6 +768,9 @@ Click on $(attach) or type \`#\` to add context, such as files to your chat. Type \`/\` to use predefined commands such as \`/help\` or \`/quarto\`.`, ), { supportThemeIcons: true, isTrusted: true }); welcomeText = welcomeText.replace('{guide-link}', `[${guideLinkMessage}](https://positron.posit.co/assistant)`); + + // Enable input for chat + this.toggleChatInputVisibility(true); } dom.clearNode(this.welcomeMessageContainer); @@ -811,6 +813,19 @@ Type \`/\` to use predefined commands such as \`/help\` or \`/quarto\`.`, dom.setVisibility(numItems !== 0, this.listContainer); } } + + private toggleChatInputVisibility(visible: boolean): void { + const input = this.container.querySelector('.interactive-input-part') as HTMLElement; + if (!input) { + console.error('ChatWidget#toggleChatInputVisibility: no input part found'); + } + if (visible) { + dom.show(input); + this.inputPart.focus(); + } else { + dom.hide(input); + } + } // --- End Positron --- private getWelcomeViewContent(): IChatWelcomeMessageContent { From 2347909684f9bc6dcab9eaca7cba072438e6d27f Mon Sep 17 00:00:00 2001 From: sharon wang Date: Wed, 25 Jun 2025 14:12:40 -0400 Subject: [PATCH 8/8] fix condition and reduce modal height --- src/vs/workbench/contrib/chat/browser/chatWidget.ts | 2 +- .../positronAssistant/browser/languageModelModalDialog.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index aecb926eb0cf..da4d448d7eca 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -741,7 +741,7 @@ export class ChatWidget extends Disposable implements IChatWidget { if (!this.configurationService.getValue('positron.assistant.enable')) { welcomeTitle = localize('positronAssistant.comingSoonTitle', "Coming Soon"); welcomeText = localize('positronAssistant.comingSoonMessage', "Positron Assistant is under development and will be available in a future version of Positron.\n"); - } else if (!!this.languageModelsService.currentProvider) { + } else if (!this.languageModelsService.currentProvider) { welcomeTitle = localize('positronAssistant.gettingStartedTitle', "Set Up Positron Assistant"); const addLanguageModelMessage = localize('positronAssistant.addLanguageModelMessage', "Add Language Model Provider"); firstLinkToButton = true; diff --git a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx index 12e58d83683e..8dc6e341bb45 100644 --- a/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx +++ b/src/vs/workbench/contrib/positronAssistant/browser/languageModelModalDialog.tsx @@ -368,7 +368,7 @@ const LanguageModelConfiguration = (props: React.PropsWithChildren localize('positron.languageModelModalDialog.close', "Close"))()} renderer={props.renderer} title={modalTitle}