Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { EditorContributionInstantiation, registerEditorContribution } from '../
import { IMenuItem, MenuRegistry, registerAction2 } from '../../../../platform/actions/common/actions.js';
import { InlineChatController, InlineChatController1, InlineChatController2 } from './inlineChatController.js';
import * as InlineChatActions from './inlineChatActions.js';
import { CTX_INLINE_CHAT_EDITING, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, INLINE_CHAT_ID, MENU_INLINE_CHAT_WIDGET_STATUS } from '../common/inlineChat.js';
import { CTX_INLINE_CHAT_EDITING, CTX_INLINE_CHAT_V1_ENABLED, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, INLINE_CHAT_ID, MENU_INLINE_CHAT_WIDGET_STATUS } from '../common/inlineChat.js';
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { LifecyclePhase } from '../../../services/lifecycle/common/lifecycle.js';
Expand Down Expand Up @@ -57,7 +57,7 @@ const editActionMenuItem: IMenuItem = {
ChatContextKeys.inputHasText,
CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.toNegated(),
CTX_INLINE_CHAT_EDITING,
CTX_INLINE_CHAT_HAS_AGENT
CTX_INLINE_CHAT_V1_ENABLED
),
};

Expand All @@ -72,7 +72,7 @@ const generateActionMenuItem: IMenuItem = {
ChatContextKeys.inputHasText,
CTX_INLINE_CHAT_REQUEST_IN_PROGRESS.toNegated(),
CTX_INLINE_CHAT_EDITING.toNegated(),
CTX_INLINE_CHAT_HAS_AGENT
CTX_INLINE_CHAT_V1_ENABLED
),
};

Expand Down
22 changes: 11 additions & 11 deletions src/vs/workbench/contrib/inlineChat/browser/inlineChatActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { EmbeddedDiffEditorWidget } from '../../../../editor/browser/widget/diff
import { EmbeddedCodeEditorWidget } from '../../../../editor/browser/widget/codeEditor/embeddedCodeEditorWidget.js';
import { EditorContextKeys } from '../../../../editor/common/editorContextKeys.js';
import { InlineChatController, InlineChatController1, InlineChatController2, InlineChatRunOptions } from './inlineChatController.js';
import { ACTION_ACCEPT_CHANGES, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_STASHED_SESSION, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, InlineChatResponseType, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, MENU_INLINE_CHAT_ZONE, ACTION_DISCARD_CHANGES, CTX_INLINE_CHAT_POSSIBLE, ACTION_START, CTX_INLINE_CHAT_HAS_AGENT2, MENU_INLINE_CHAT_SIDE } from '../common/inlineChat.js';
import { ACTION_ACCEPT_CHANGES, CTX_INLINE_CHAT_HAS_STASHED_SESSION, CTX_INLINE_CHAT_FOCUSED, CTX_INLINE_CHAT_INNER_CURSOR_FIRST, CTX_INLINE_CHAT_INNER_CURSOR_LAST, CTX_INLINE_CHAT_VISIBLE, CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET_STATUS, CTX_INLINE_CHAT_REQUEST_IN_PROGRESS, CTX_INLINE_CHAT_RESPONSE_TYPE, InlineChatResponseType, ACTION_REGENERATE_RESPONSE, ACTION_VIEW_IN_CHAT, ACTION_TOGGLE_DIFF, CTX_INLINE_CHAT_CHANGE_HAS_DIFF, CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF, MENU_INLINE_CHAT_ZONE, ACTION_DISCARD_CHANGES, CTX_INLINE_CHAT_POSSIBLE, ACTION_START, MENU_INLINE_CHAT_SIDE, CTX_INLINE_CHAT_V2_ENABLED, CTX_INLINE_CHAT_V1_ENABLED } from '../common/inlineChat.js';
import { ctxHasEditorModification, ctxHasRequestInProgress, ctxIsGlobalEditingSession, ctxRequestCount } from '../../chat/browser/chatEditing/chatEditingEditorContextKeys.js';
import { localize, localize2 } from '../../../../nls.js';
import { Action2, IAction2Options, MenuId } from '../../../../platform/actions/common/actions.js';
Expand Down Expand Up @@ -49,7 +49,7 @@ export function setHoldForSpeech(holdForSpeech: IHoldForSpeech) {
}

const inlineChatContextKey = ContextKeyExpr.and(
ContextKeyExpr.or(CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_AGENT2),
ContextKeyExpr.or(CTX_INLINE_CHAT_V1_ENABLED, CTX_INLINE_CHAT_V2_ENABLED),
CTX_INLINE_CHAT_POSSIBLE,
EditorContextKeys.writable,
EditorContextKeys.editorSimpleInput.negate()
Expand Down Expand Up @@ -189,10 +189,10 @@ export abstract class AbstractInline1ChatAction extends EditorAction2 {
const massageMenu = (menu: IAction2Options['menu'] | undefined) => {
if (Array.isArray(menu)) {
for (const entry of menu) {
entry.when = ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT, entry.when);
entry.when = ContextKeyExpr.and(CTX_INLINE_CHAT_V1_ENABLED, entry.when);
}
} else if (menu) {
menu.when = ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT, menu.when);
menu.when = ContextKeyExpr.and(CTX_INLINE_CHAT_V1_ENABLED, menu.when);
}
};
if (Array.isArray(desc.menu)) {
Expand All @@ -204,7 +204,7 @@ export abstract class AbstractInline1ChatAction extends EditorAction2 {
super({
...desc,
category: AbstractInline1ChatAction.category,
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT, desc.precondition)
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_V1_ENABLED, desc.precondition)
});
}

Expand Down Expand Up @@ -558,10 +558,10 @@ abstract class AbstractInline2ChatAction extends EditorAction2 {
const massageMenu = (menu: IAction2Options['menu'] | undefined) => {
if (Array.isArray(menu)) {
for (const entry of menu) {
entry.when = ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, entry.when);
entry.when = ContextKeyExpr.and(CTX_INLINE_CHAT_V2_ENABLED, entry.when);
}
} else if (menu) {
menu.when = ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, menu.when);
menu.when = ContextKeyExpr.and(CTX_INLINE_CHAT_V2_ENABLED, menu.when);
}
};
if (Array.isArray(desc.menu)) {
Expand All @@ -573,7 +573,7 @@ abstract class AbstractInline2ChatAction extends EditorAction2 {
super({
...desc,
category: AbstractInline2ChatAction.category,
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, desc.precondition)
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_V2_ENABLED, desc.precondition)
});
}

Expand Down Expand Up @@ -637,7 +637,7 @@ class KeepOrUndoSessionAction extends AbstractInline2ChatAction {
id: MENU_INLINE_CHAT_WIDGET_STATUS,
group: '0_main',
order: 1,
when: ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, ContextKeyExpr.greater(ctxRequestCount.key, 0), ctxHasEditorModification),
when: ContextKeyExpr.and(ContextKeyExpr.greater(ctxRequestCount.key, 0), ctxHasEditorModification),
}]
});
}
Expand Down Expand Up @@ -696,12 +696,12 @@ export class CloseSessionAction2 extends AbstractInline2ChatAction {
menu: [{
id: MENU_INLINE_CHAT_SIDE,
group: 'navigation',
when: ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, ctxRequestCount.isEqualTo(0)),
when: ContextKeyExpr.and(ctxRequestCount.isEqualTo(0)),
}, {
id: MENU_INLINE_CHAT_WIDGET_STATUS,
group: '0_main',
order: 1,
when: ContextKeyExpr.and(CTX_INLINE_CHAT_HAS_AGENT2, ctxHasEditorModification.negate()),
when: ContextKeyExpr.and(ctxHasEditorModification.negate()),
}]
});
}
Expand Down
22 changes: 11 additions & 11 deletions src/vs/workbench/contrib/inlineChat/browser/inlineChatController.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,12 +127,14 @@ export class InlineChatController implements IEditorContribution {
constructor(
editor: ICodeEditor,
@IConfigurationService configurationService: IConfigurationService,
@INotebookEditorService private readonly _notebookEditorService: INotebookEditorService
) {

const inlineChat2 = observableConfigValue(InlineChatConfigKeys.EnableV2, false, configurationService);
const notebookAgent = observableConfigValue(InlineChatConfigKeys.notebookAgent, false, configurationService);

this._delegate = derived(r => {
if (inlineChat2.read(r)) {
const isNotebookCell = this._notebookEditorService.isCellEditor(editor);
if (isNotebookCell ? notebookAgent.read(r) : inlineChat2.read(r)) {
return InlineChatController2.get(editor)!;
} else {
return InlineChatController1.get(editor)!;
Expand Down Expand Up @@ -1315,16 +1317,14 @@ export class InlineChatController2 implements IEditorContribution {
location.location = ChatAgentLocation.Notebook;
notebookEditor = editor;
// set location2 so that the notebook agent intent is used
if (configurationService.getValue(InlineChatConfigKeys.notebookAgent)) {
location.resolveData = () => {
assertType(this._editor.hasModel());

return {
type: ChatAgentLocation.Notebook,
sessionInputUri: this._editor.getModel().uri,
};
location.resolveData = () => {
assertType(this._editor.hasModel());

return {
type: ChatAgentLocation.Notebook,
sessionInputUri: this._editor.getModel().uri,
};
}
};

break;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ import { IChatAgentService } from '../../chat/common/chatAgents.js';
import { ChatAgentLocation } from '../../chat/common/constants.js';
import { MODE_FILE_EXTENSION } from '../../chat/common/promptSyntax/config/promptFileLocations.js';
import { INSTRUCTIONS_LANGUAGE_ID, PROMPT_LANGUAGE_ID } from '../../chat/common/promptSyntax/promptTypes.js';
import { ACTION_START, CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_VISIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
import { ACTION_START, CTX_INLINE_CHAT_V1_ENABLED, CTX_INLINE_CHAT_VISIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
import { AbstractInline1ChatAction } from './inlineChatActions.js';
import { InlineChatController } from './inlineChatController.js';
import './media/inlineChat.css';
Expand Down Expand Up @@ -66,7 +66,7 @@ export class InlineChatExpandLineAction extends EditorAction2 {
category: AbstractInline1ChatAction.category,
title: localize2('startWithCurrentLine', "Start in Editor with Current Line"),
f1: true,
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE.negate(), CTX_INLINE_CHAT_HAS_AGENT, EditorContextKeys.writable),
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE.negate(), CTX_INLINE_CHAT_V1_ENABLED, EditorContextKeys.writable),
keybinding: [{
when: CTX_INLINE_CHAT_SHOWING_HINT,
weight: KeybindingWeight.WorkbenchContrib + 1,
Expand Down Expand Up @@ -119,7 +119,7 @@ export class ShowInlineChatHintAction extends EditorAction2 {
category: AbstractInline1ChatAction.category,
title: localize2('showHint', "Show Inline Chat Hint"),
f1: false,
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE.negate(), CTX_INLINE_CHAT_HAS_AGENT, EditorContextKeys.writable),
precondition: ContextKeyExpr.and(CTX_INLINE_CHAT_VISIBLE.negate(), CTX_INLINE_CHAT_V1_ENABLED, EditorContextKeys.writable),
});
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ import { IChatAgentService } from '../../chat/common/chatAgents.js';
import { ModifiedFileEntryState } from '../../chat/common/chatEditingService.js';
import { IChatService } from '../../chat/common/chatService.js';
import { ChatAgentLocation } from '../../chat/common/constants.js';
import { CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_AGENT2, CTX_INLINE_CHAT_POSSIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
import { CTX_INLINE_CHAT_HAS_AGENT, CTX_INLINE_CHAT_HAS_AGENT2, CTX_INLINE_CHAT_HAS_NOTEBOOK_AGENT, CTX_INLINE_CHAT_HAS_NOTEBOOK_INLINE, CTX_INLINE_CHAT_POSSIBLE, InlineChatConfigKeys } from '../common/inlineChat.js';
import { HunkData, Session, SessionWholeRange, StashedSession, TelemetryData, TelemetryDataClassification } from './inlineChatSession.js';
import { IInlineChatSession2, IInlineChatSessionEndEvent, IInlineChatSessionEvent, IInlineChatSessionService, ISessionKeyComputer } from './inlineChatSessionService.js';

Expand Down Expand Up @@ -417,6 +417,8 @@ export class InlineChatEnabler {

private readonly _ctxHasProvider: IContextKey<boolean>;
private readonly _ctxHasProvider2: IContextKey<boolean>;
private readonly _ctxHasNotebookInline: IContextKey<boolean>;
private readonly _ctxHasNotebookProvider: IContextKey<boolean>;
private readonly _ctxPossible: IContextKey<boolean>;

private readonly _store = new DisposableStore();
Expand All @@ -429,10 +431,14 @@ export class InlineChatEnabler {
) {
this._ctxHasProvider = CTX_INLINE_CHAT_HAS_AGENT.bindTo(contextKeyService);
this._ctxHasProvider2 = CTX_INLINE_CHAT_HAS_AGENT2.bindTo(contextKeyService);
this._ctxHasNotebookInline = CTX_INLINE_CHAT_HAS_NOTEBOOK_INLINE.bindTo(contextKeyService);
this._ctxHasNotebookProvider = CTX_INLINE_CHAT_HAS_NOTEBOOK_AGENT.bindTo(contextKeyService);
this._ctxPossible = CTX_INLINE_CHAT_POSSIBLE.bindTo(contextKeyService);

const agentObs = observableFromEvent(this, chatAgentService.onDidChangeAgents, () => chatAgentService.getDefaultAgent(ChatAgentLocation.EditorInline));
const inlineChat2Obs = observableConfigValue(InlineChatConfigKeys.EnableV2, false, configService);
const notebookAgentObs = observableFromEvent(this, chatAgentService.onDidChangeAgents, () => chatAgentService.getDefaultAgent(ChatAgentLocation.Notebook));
const notebookAgentConfigObs = observableConfigValue(InlineChatConfigKeys.notebookAgent, false, configService);

this._store.add(autorun(r => {
const v2 = inlineChat2Obs.read(r);
Expand All @@ -449,6 +455,11 @@ export class InlineChatEnabler {
}
}));

this._store.add(autorun(r => {
this._ctxHasNotebookInline.set(!notebookAgentConfigObs.read(r) && !!agentObs.read(r));
this._ctxHasNotebookProvider.set(notebookAgentConfigObs.read(r) && !!notebookAgentObs.read(r));
}));

const updateEditor = () => {
const ctrl = editorService.activeEditorPane?.getControl();
const isCodeEditorLike = isCodeEditor(ctrl) || isDiffEditor(ctrl) || isCompositeEditor(ctrl);
Expand Down
16 changes: 14 additions & 2 deletions src/vs/workbench/contrib/inlineChat/common/inlineChat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
import { localize } from '../../../../nls.js';
import { MenuId } from '../../../../platform/actions/common/actions.js';
import { Extensions, IConfigurationRegistry } from '../../../../platform/configuration/common/configurationRegistry.js';
import { RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
import { ContextKeyExpr, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { diffInserted, diffRemoved, editorWidgetBackground, editorWidgetBorder, editorWidgetForeground, focusBorder, inputBackground, inputPlaceholderForeground, registerColor, transparent, widgetShadow } from '../../../../platform/theme/common/colorRegistry.js';
import { NOTEBOOK_IS_ACTIVE_EDITOR } from '../../notebook/common/notebookContextKeys.js';

// settings

Expand Down Expand Up @@ -104,7 +105,9 @@ export const enum InlineChatResponseType {

export const CTX_INLINE_CHAT_POSSIBLE = new RawContextKey<boolean>('inlineChatPossible', false, localize('inlineChatHasPossible', "Whether a provider for inline chat exists and whether an editor for inline chat is open"));
export const CTX_INLINE_CHAT_HAS_AGENT = new RawContextKey<boolean>('inlineChatHasProvider', false, localize('inlineChatHasProvider', "Whether a provider for interactive editors exists"));
export const CTX_INLINE_CHAT_HAS_AGENT2 = new RawContextKey<boolean>('inlineChatHasEditsAgent', false, localize('inlineChatHasEditsAgent', "Whether an agent for inliine for interactive editors exists"));
export const CTX_INLINE_CHAT_HAS_AGENT2 = new RawContextKey<boolean>('inlineChatHasEditsAgent', false, localize('inlineChatHasEditsAgent', "Whether an agent for inline for interactive editors exists"));
export const CTX_INLINE_CHAT_HAS_NOTEBOOK_INLINE = new RawContextKey<boolean>('inlineChatHasNotebookInline', false, localize('inlineChatHasNotebookInline', "Whether an agent for notebook cells exists"));
export const CTX_INLINE_CHAT_HAS_NOTEBOOK_AGENT = new RawContextKey<boolean>('inlineChatHasNotebookAgent', false, localize('inlineChatHasNotebookAgent', "Whether an agent for notebook cells exists"));
export const CTX_INLINE_CHAT_VISIBLE = new RawContextKey<boolean>('inlineChatVisible', false, localize('inlineChatVisible', "Whether the interactive editor input is visible"));
export const CTX_INLINE_CHAT_FOCUSED = new RawContextKey<boolean>('inlineChatFocused', false, localize('inlineChatFocused', "Whether the interactive editor input is focused"));
export const CTX_INLINE_CHAT_EDITING = new RawContextKey<boolean>('inlineChatEditing', true, localize('inlineChatEditing', "Whether the user is currently editing or generating code in the inline chat"));
Expand All @@ -119,6 +122,15 @@ export const CTX_INLINE_CHAT_CHANGE_SHOWS_DIFF = new RawContextKey<boolean>('inl
export const CTX_INLINE_CHAT_REQUEST_IN_PROGRESS = new RawContextKey<boolean>('inlineChatRequestInProgress', false, localize('inlineChatRequestInProgress', "Whether an inline chat request is currently in progress"));
export const CTX_INLINE_CHAT_RESPONSE_TYPE = new RawContextKey<InlineChatResponseType>('inlineChatResponseType', InlineChatResponseType.None, localize('inlineChatResponseTypes', "What type was the responses have been receieved, nothing yet, just messages, or messaged and local edits"));

export const CTX_INLINE_CHAT_V1_ENABLED = ContextKeyExpr.or(
ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR.negate(), CTX_INLINE_CHAT_HAS_AGENT),
ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CTX_INLINE_CHAT_HAS_NOTEBOOK_INLINE)
);

export const CTX_INLINE_CHAT_V2_ENABLED = ContextKeyExpr.or(
ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR.negate(), CTX_INLINE_CHAT_HAS_AGENT2),
ContextKeyExpr.and(NOTEBOOK_IS_ACTIVE_EDITOR, CTX_INLINE_CHAT_HAS_NOTEBOOK_AGENT)
);

// --- (selected) action identifier

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { Event } from '../../../../../base/common/event.js';
import { Dimension } from '../../../../../base/browser/dom.js';
import { NotebookEditorWidget } from '../notebookEditorWidget.js';
import { URI } from '../../../../../base/common/uri.js';
import { ICodeEditor } from '../../../../../editor/browser/editorBrowser.js';

export const INotebookEditorService = createDecorator<INotebookEditorService>('INotebookEditorWidgetService');

Expand All @@ -30,5 +31,6 @@ export interface INotebookEditorService {
removeNotebookEditor(editor: INotebookEditor): void;
getNotebookEditor(editorId: string): INotebookEditor | undefined;
listNotebookEditors(): readonly INotebookEditor[];
isCellEditor(editor: ICodeEditor): boolean;
updateReplContextKey(uri: string): void;
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { InteractiveWindowOpen, MOST_RECENT_REPL_EDITOR } from '../../common/not
import { ServiceCollection } from '../../../../../platform/instantiation/common/serviceCollection.js';
import { IEditorProgressService } from '../../../../../platform/progress/common/progress.js';
import { NotebookDiffEditorInput } from '../../common/notebookDiffEditorInput.js';
import { ICodeEditor } from '../../../../../editor/browser/editorBrowser.js';

export class NotebookEditorWidgetService implements INotebookEditorService {

Expand Down Expand Up @@ -288,6 +289,15 @@ export class NotebookEditorWidgetService implements INotebookEditorService {
return [...this._notebookEditors].map(e => e[1]);
}

isCellEditor(candidate: ICodeEditor): boolean {
for (const editor of this._notebookEditors.values()) {
for (const [, codeEditor] of editor.codeEditors) {
return codeEditor === candidate;
}
}
return false;
}

updateReplContextKey(uri: string): void {
this._mostRecentRepl.set(uri);
}
Expand Down
Loading