Skip to content
Merged
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 @@ -44,6 +44,7 @@ export const enum TerminalChatContextKeyStrings {
ChatResponseContainsMultipleCodeBlocks = 'terminalChatResponseContainsMultipleCodeBlocks',
ChatResponseSupportsIssueReporting = 'terminalChatResponseSupportsIssueReporting',
ChatSessionResponseVote = 'terminalChatSessionResponseVote',
ChatUsesAgentHost = 'terminalChatUsesAgentHost',
ChatHasTerminals = 'hasChatTerminals',
ChatHasHiddenTerminals = 'hasHiddenChatTerminals',
ChatToolHasInstance = 'chatTerminalToolHasInstance',
Expand Down Expand Up @@ -78,6 +79,9 @@ export namespace TerminalChatContextKeys {
/** A chat agent exists for the terminal location */
export const hasChatAgent = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatAgentRegistered, false, localize('chatAgentRegisteredContextKey', "Whether a chat agent is registered for the terminal location."));

/** Whether the chat session is backed by the Agent Host */
export const usesAgentHost = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatUsesAgentHost, false, localize('terminalChatUsesAgentHostContextKey', "Whether the terminal chat session is backed by the Agent Host."));

/** Has terminals created via chat */
export const hasChatTerminals = new RawContextKey<boolean>(TerminalChatContextKeyStrings.ChatHasTerminals, false, localize('terminalHasChatTerminals', "Whether there are any chat terminals."));

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -300,14 +300,15 @@ registerActiveXtermAction({
ChatContextKeys.enabled,
ContextKeyExpr.or(TerminalContextKeys.processSupported, TerminalContextKeys.terminalHasBeenCreated),
TerminalChatContextKeys.requestActive.negate(),
TerminalChatContextKeys.usesAgentHost.negate(),
),
icon: Codicon.chatSparkle,
menu: [{
id: MENU_TERMINAL_CHAT_WIDGET_STATUS,
group: 'zzz',
order: 1,
isHiddenByDefault: true,
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.requestActive.negate()),
when: ContextKeyExpr.and(TerminalChatContextKeys.responseContainsCodeBlock, TerminalChatContextKeys.requestActive.negate(), TerminalChatContextKeys.usesAgentHost.negate()),
}],
run: (_xterm, _accessor, activeInstance) => {
if (isDetachedTerminalInstance(activeInstance)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ export class TerminalChatWidget extends Disposable {
private readonly _requestActiveContextKey: IContextKey<boolean>;
private readonly _responseContainsCodeBlockContextKey: IContextKey<boolean>;
private readonly _responseContainsMulitpleCodeBlocksContextKey: IContextKey<boolean>;
private readonly _usesAgentHostContextKey: IContextKey<boolean>;

private _messages = this._store.add(new Emitter<Message>());

Expand Down Expand Up @@ -130,6 +131,7 @@ export class TerminalChatWidget extends Disposable {
this._requestActiveContextKey = TerminalChatContextKeys.requestActive.bindTo(contextKeyService);
this._responseContainsCodeBlockContextKey = TerminalChatContextKeys.responseContainsCodeBlock.bindTo(contextKeyService);
this._responseContainsMulitpleCodeBlocksContextKey = TerminalChatContextKeys.responseContainsMultipleCodeBlocks.bindTo(contextKeyService);
this._usesAgentHostContextKey = TerminalChatContextKeys.usesAgentHost.bindTo(contextKeyService);

this._container = document.createElement('div');
this._container.classList.add('terminal-inline-chat');
Expand Down Expand Up @@ -367,10 +369,12 @@ export class TerminalChatWidget extends Disposable {
if (lockToAgent) {
this._inlineChatWidget.chatWidget.lockToCodingAgent(lockToAgent.name, lockToAgent.displayName, lockToAgent.type, lockToAgent.agentHostProviderId);
this._agentHostSessionResource = model.sessionResource;
this._usesAgentHostContextKey.set(true);
this._refreshAgentHostSessionMetadata();
} else {
this._inlineChatWidget.chatWidget.unlockFromCodingAgent();
this._agentHostSessionResource = undefined;
this._usesAgentHostContextKey.set(false);
}
this._resetPlaceholder();
});
Expand Down Expand Up @@ -425,6 +429,7 @@ export class TerminalChatWidget extends Disposable {
this.cancel();
this._model.clear();
this._agentHostSessionResource = undefined;
this._usesAgentHostContextKey.reset();
this._inlineChatWidget.chatWidget.unlockFromCodingAgent();
this._responseContainsCodeBlockContextKey.reset();
this._requestActiveContextKey.reset();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import assert from 'assert';
import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../../base/test/common/utils.js';
import { isIMenuItem, MenuRegistry } from '../../../../../../platform/actions/common/actions.js';
import { ContextKeyValue, IContext } from '../../../../../../platform/contextkey/common/contextkey.js';
import '../../browser/terminalChatActions.js';
import { MENU_TERMINAL_CHAT_WIDGET_STATUS, TerminalChatCommandId, TerminalChatContextKeys } from '../../browser/terminalChat.js';

suite('Terminal Chat actions', () => {

ensureNoDisposablesAreLeakedInTestSuite();

function hasViewInChat(overrides: Record<string, ContextKeyValue>): boolean {
const context: IContext = {
getValue: <T extends ContextKeyValue>(key: string): T | undefined => overrides[key] as T | undefined,
};
return MenuRegistry.getMenuItems(MENU_TERMINAL_CHAT_WIDGET_STATUS)
.filter(isIMenuItem)
.some(item => item.command.id === TerminalChatCommandId.ViewInChat && (!item.when || item.when.evaluate(context)));
}

test('shows View in Chat only for local terminal chat sessions', () => {
const base = {
[TerminalChatContextKeys.responseContainsCodeBlock.key]: true,
[TerminalChatContextKeys.requestActive.key]: false,
};

assert.deepStrictEqual({
local: hasViewInChat({ ...base, [TerminalChatContextKeys.usesAgentHost.key]: false }),
agentHost: hasViewInChat({ ...base, [TerminalChatContextKeys.usesAgentHost.key]: true }),
}, {
local: true,
agentHost: false,
});
});
});
Loading