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 @@ -36,7 +36,7 @@ import { IWorkbenchContribution, WorkbenchPhase, registerWorkbenchContribution2
import { ConfigurationKeyValuePairs, IConfigurationMigrationRegistry, Extensions as WorkbenchConfigurationExtensions } from '../../../common/configuration.js';
import { IStorageService, StorageScope, StorageTarget } from '../../../../platform/storage/common/storage.js';

import { AgentsVoiceSettingId, AgentsVoiceStorageKeys, AGENTS_VOICE_CONNECTED, AGENTS_VOICE_CONNECTING, AGENTS_VOICE_ENABLED, AGENTS_VOICE_ENTITLED, AGENTS_VOICE_LISTENING, AGENTS_VOICE_RECONNECTING, getAgentsVoicePolicyValue } from '../common/agentsVoice.js';
import { AgentsVoiceSettingId, AgentsVoiceStorageKeys, AGENTS_VOICE_CONNECTED, AGENTS_VOICE_CONNECTING, AGENTS_VOICE_ENABLED, AGENTS_VOICE_ENTITLED, AGENTS_VOICE_LISTENING, AGENTS_VOICE_MUTED, AGENTS_VOICE_RECONNECTING, getAgentsVoicePolicyValue } from '../common/agentsVoice.js';
import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js';
import { IChatEntitlementService } from '../../../services/chat/common/chatEntitlementService.js';
import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js';
Expand Down Expand Up @@ -103,11 +103,13 @@ class AgentsVoiceConnectedKeyContribution extends Disposable implements IWorkben
const connectingKey = AGENTS_VOICE_CONNECTING.bindTo(contextKeyService);
const listeningKey = AGENTS_VOICE_LISTENING.bindTo(contextKeyService);
const reconnectingKey = AGENTS_VOICE_RECONNECTING.bindTo(contextKeyService);
const mutedKey = AGENTS_VOICE_MUTED.bindTo(contextKeyService);
this._register(autorun(reader => {
connectedKey.set(voiceSessionController.isConnected.read(reader));
connectingKey.set(voiceSessionController.isConnecting.read(reader));
reconnectingKey.set(voiceSessionController.isReconnecting.read(reader));
listeningKey.set(voiceSessionController.voiceState.read(reader) === 'listening');
mutedKey.set(voiceSessionController.isMuted.read(reader));
}));
}
}
Expand Down Expand Up @@ -422,6 +424,46 @@ registerAction2(class extends Action2 {
}
});

// --- Toggle Mute Microphone (command palette + keybinding) ---
//
// Voice Mode is always listening while connected, so it can pick up
// conversations the user is having with others. Muting keeps the session
// connected (so the user can resume instantly) while dropping captured audio.
// Expose it as a keybindable command so users can mute/unmute without reaching
// for the mute button.

registerAction2(class extends Action2 {
constructor() {
super({
id: 'agentsVoice.toggleMute',
title: nls.localize2('agentsVoice.toggleMute', "Voice Mode: Toggle Mute Microphone"),
f1: true,
toggled: {
condition: AGENTS_VOICE_MUTED.isEqualTo(true),
title: nls.localize('agentsVoice.unmuteMic', "Unmute Microphone"),
},
precondition: ContextKeyExpr.and(
AGENTS_VOICE_ENABLED,
AGENTS_VOICE_CONNECTED.isEqualTo(true),
),
keybinding: {
weight: KeybindingWeight.WorkbenchContrib + 1,
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KeyM,
when: ContextKeyExpr.and(
AGENTS_VOICE_ENABLED,
AGENTS_VOICE_CONNECTED.isEqualTo(true),
VOICE_ACTIVE_ON_SURFACE,
ChatContextKeys.inputHasFocus,
),
},
});
}
async run(accessor: ServicesAccessor): Promise<void> {
const voiceController = accessor.get(IVoiceSessionController);
voiceController.setMuted(!voiceController.isMuted.get());
}
});

// --- Cancel Active Request via Escape (while voice-connected in the chat input) ---
//
// The Disconnect-on-Escape action above deliberately does NOTHING while a
Expand Down
1 change: 1 addition & 0 deletions src/vs/workbench/contrib/agentsVoice/common/agentsVoice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const AGENTS_VOICE_CONNECTED = new RawContextKey<boolean>('agentsVoiceCon
export const AGENTS_VOICE_CONNECTING = new RawContextKey<boolean>('agentsVoiceConnecting', false);
export const AGENTS_VOICE_RECONNECTING = new RawContextKey<boolean>('agentsVoiceReconnecting', false);
export const AGENTS_VOICE_LISTENING = new RawContextKey<boolean>('agentsVoiceListening', false);
export const AGENTS_VOICE_MUTED = new RawContextKey<boolean>('agentsVoiceMuted', false);
/**
* True when the current Copilot entitlement permits Voice Mode. This is a single
* key set imperatively from `IChatEntitlementService` (see
Expand Down