Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
48fc9bf
plan widget: show implementation dropdown when plan is open (#334381)
justschen Sep 4, 2026
a92c2f9
Fix chat response jump by reserving space for visible chat pets (#334…
justschen Sep 4, 2026
60e6485
Stop ABExp.queriedFeature telemetry from being redacted as a file pat…
vijayupadya Sep 4, 2026
dbdc289
chat: Add setting for subagent credit usage (#334384)
justschen Sep 4, 2026
2a9aad2
sessions: rename focused chat with F2 (#334163)
DonJayamanne Sep 4, 2026
8cc6591
Fixes github pr and issue link presentation data fetching (#334374)
hediet Sep 4, 2026
06c80b3
chat: fix picker focus and keyboard navigation (#334416)
justschen Sep 4, 2026
dee137a
Align Agent Host sandbox network and credential defaults (#334390)
dileepyavan Sep 4, 2026
3aa2577
Add experimental Opus thinking effort setting (#334426)
bhavyaus Sep 4, 2026
55af5ce
Keep sandbox toggle editable when managed policy allows bypass (#334370)
dileepyavan Sep 4, 2026
85ce8ef
sessions: add Agents window layout telemetry (#334255)
sandy081 Sep 4, 2026
ee99b8a
Agents - fix vertical alignment of the badge number (#334430)
lszomoru Sep 4, 2026
df0ea76
Support opening MHTML files in integrated browser (#333307)
YOSHII-Hiroto Sep 4, 2026
463b2fb
sessions: polish: add new session button treatments (#334269)
ulugbekna Sep 4, 2026
dac655d
Prevent duplicate implicit PR attachments (#334215)
Copilot Sep 4, 2026
be6bce2
Implement queueing for busy target chats in send_message tool (#334260)
sandy081 Sep 4, 2026
5e43680
Update file icon mask properties for better alignment and sizing (#33…
mrleemurray Sep 4, 2026
a9864c0
Convert workspace-less sessions to workspace sessions (#334250)
sandy081 Sep 4, 2026
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
2 changes: 1 addition & 1 deletion build/lib/policies/policyData.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@
}
},
"type": "boolean",
"default": false,
"default": true,
"included": true
},
{
Expand Down
16 changes: 16 additions & 0 deletions extensions/copilot/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4144,6 +4144,22 @@
"onExp"
]
},
"github.copilot.chat.claudeOpusDefaultReasoningEffort": {
"type": "string",
"default": "",
"enum": [
"",
"low",
"medium",
"high",
"max"
],
"markdownDescription": "%github.copilot.config.claudeOpusDefaultReasoningEffort%",
"tags": [
"experimental",
"onExp"
]
},
"github.copilot.chat.gpt55ReadFileTool.enabled": {
"type": "boolean",
"default": true,
Expand Down
1 change: 1 addition & 0 deletions extensions/copilot/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,7 @@
"github.copilot.config.gpt56Verbosity.enabled": "Sets the response verbosity to low for gpt-5.6 models.",
"github.copilot.config.gemini3GetChangedFilesTool.enabled": "Enables the Get Changed Files tool for gemini-3 models.",
"github.copilot.config.gemini3LowReasoningEffort.enabled": "Sets the reasoning effort to low for gemini-3 models.",
"github.copilot.config.claudeOpusDefaultReasoningEffort": "Overrides the default thinking effort shown in the model picker for Claude Opus models. Leave empty to use the built-in default. Ignored if the model does not support the chosen level.",
"github.copilot.config.gpt55ReadFileTool.enabled": "Enables the Read File tool for gpt-5.5 models.",
"github.copilot.config.anthropic.tools.websearch.enabled": "Enable Anthropic's native web search tool for BYOK Claude models. When enabled, allows Claude to search the web for current information. \n\n**Note**: This is an experimental feature only available for BYOK Anthropic Claude models.",
"github.copilot.config.anthropic.tools.websearch.maxUses": "Maximum number of web searches allowed per request. Valid range is 1 to 20. Prevents excessive API calls within a single interaction. If Claude exceeds this limit, the response returns an error.",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,17 @@ export function getReasoningEffortLabel(level: string): string {
* Builds the `reasoningEffort` property descriptor for a model's
* {@link LanguageModelConfigurationSchema}. Centralises the default-selection
* and localized descriptions so the picker stays consistent across the
* Copilot and BYOK code paths.
* Copilot and BYOK code paths. `defaultOverride` wins over the family default
* when it is one of the advertised levels.
*/
export function buildReasoningEffortSchemaProperty(effortLevels: readonly string[], family: string): NonNullable<LanguageModelConfigurationSchema['properties']>[string] {
export function buildReasoningEffortSchemaProperty(effortLevels: readonly string[], family: string, defaultOverride?: string): NonNullable<LanguageModelConfigurationSchema['properties']>[string] {
return {
type: 'string',
title: l10n.t('Thinking Effort'),
enum: effortLevels,
enumItemLabels: effortLevels.map(getReasoningEffortLabel),
enumDescriptions: effortLevels.map(getReasoningEffortDescription),
default: pickDefaultReasoningEffort(effortLevels, family),
default: defaultOverride && effortLevels.includes(defaultOverride) ? defaultOverride : pickDefaultReasoningEffort(effortLevels, family),
group: 'navigation',
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { IAuthenticationService } from '../../../platform/authentication/common/
import { CopilotToken } from '../../../platform/authentication/common/copilotToken';
import { IBlockedExtensionService } from '../../../platform/chat/common/blockedExtensionService';
import { ChatFetchResponseType, ChatLocation, getErrorDetailsFromChatFetchError } from '../../../platform/chat/common/commonTypes';
import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';
import { getTextPart } from '../../../platform/chat/common/globalStringUtils';
import { EmbeddingType, getWellKnownEmbeddingTypeInfo, IEmbeddingsComputer } from '../../../platform/embeddings/common/embeddingsComputer';
import { AUTO_MODE_TIER_PROPERTY, defaultAutoModeTier, selectableAutoModeTiers } from '../../../platform/endpoint/common/autoModeTiers';
Expand Down Expand Up @@ -119,7 +120,7 @@ function buildAutoRoutingContext(

// Auto model delegates to different backends, so the only picker it exposes is
// the routing tier; per-model options belong to the model it routes to.
function buildConfigurationSchema(endpoint: IChatEndpoint, autoTiersEnabled: boolean): { configurationSchema?: vscode.LanguageModelConfigurationSchema } {
function buildConfigurationSchema(endpoint: IChatEndpoint, autoTiersEnabled: boolean, opusDefaultEffort: string | undefined): { configurationSchema?: vscode.LanguageModelConfigurationSchema } {
if (endpoint instanceof AutoChatEndpoint) {
return autoTiersEnabled
? { configurationSchema: { properties: { [AUTO_MODE_TIER_PROPERTY]: buildAutoModeTierSchemaProperty(selectableAutoModeTiers, defaultAutoModeTier) } } }
Expand All @@ -131,7 +132,9 @@ function buildConfigurationSchema(endpoint: IChatEndpoint, autoTiersEnabled: boo
// Reasoning effort config
const effortLevels = endpoint.supportsReasoningEffort;
if (effortLevels && effortLevels.length > 1) {
properties.reasoningEffort = buildReasoningEffortSchemaProperty(effortLevels, endpoint.family.toLowerCase());
const family = endpoint.family.toLowerCase();
const defaultOverride = family.includes('opus') ? opusDefaultEffort : undefined;
properties.reasoningEffort = buildReasoningEffortSchemaProperty(effortLevels, family, defaultOverride);
}

// Context size config
Expand Down Expand Up @@ -246,6 +249,7 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
@IVSCodeExtensionContext private readonly _vsCodeExtensionContext: IVSCodeExtensionContext,
@IAutomodeService private readonly _automodeService: IAutomodeService,
@IExperimentationService private readonly _expService: IExperimentationService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
) {
super();

Expand Down Expand Up @@ -299,6 +303,11 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
// honored while routing goes through `POST /auto`.
this._onDidChange.fire();
}));
this._register(this._configurationService.onDidChangeConfiguration(e => {
if (e.affectsConfiguration(ConfigKey.ClaudeOpusDefaultReasoningEffort.fullyQualifiedId)) {
this._onDidChange.fire();
}
}));
void this._refreshUtilityOverrides().catch(err => {
this._logService.warn(`[LanguageModelAccess] Failed to pre-resolve internal model aliases: ${err}`);
});
Expand Down Expand Up @@ -332,6 +341,7 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib

const seenFamilies = new Set<string>();
const autoTiersEnabled = this._automodeService.areAutoModeTiersSupported();
const opusDefaultEffort = this._configurationService.getExperimentBasedConfig(ConfigKey.ClaudeOpusDefaultReasoningEffort, this._expService) || undefined;

for (const endpoint of chatEndpoints) {
if (seenFamilies.has(endpoint.family) && !endpoint.showInModelPicker) {
Expand Down Expand Up @@ -410,7 +420,7 @@ export class LanguageModelAccess extends Disposable implements IExtensionContrib
imageInput: endpoint instanceof AutoChatEndpoint ? true : endpoint.supportsVision,
toolCalling: endpoint.supportsToolCalls,
},
...buildConfigurationSchema(endpoint, autoTiersEnabled),
...buildConfigurationSchema(endpoint, autoTiersEnabled, opusDefaultEffort),
};

models.push(model);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -691,6 +691,12 @@ suite('reasoning effort schema', () => {
assert.deepStrictEqual(prop.enum, ['low', 'high']);
assert.strictEqual(prop.group, 'navigation');
});

test('buildReasoningEffortSchemaProperty honors a default override only when advertised', () => {
assert.strictEqual(buildReasoningEffortSchemaProperty(['low', 'medium', 'high'], 'claude-opus-4.5', 'medium').default, 'medium');
assert.strictEqual(buildReasoningEffortSchemaProperty(['low', 'high'], 'claude-opus-4.5', 'medium').default, 'high');
assert.strictEqual(buildReasoningEffortSchemaProperty(['low', 'medium', 'high'], 'claude-opus-4.5', undefined).default, 'high');
});
});

suite('auto mode tier schema', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1123,6 +1123,8 @@ export namespace ConfigKey {
export const EnableGemini3GetChangedFilesTool = defineSetting<boolean>('chat.gemini3GetChangedFilesTool.enabled', ConfigType.ExperimentBased, false);
/** When enabled, sends `reasoning_effort: 'low'` to Gemini 3 models. */
export const EnableGemini3LowReasoningEffort = defineSetting<boolean>('chat.gemini3LowReasoningEffort.enabled', ConfigType.ExperimentBased, false);
/** Default thinking effort for Claude Opus models in the model picker. Empty keeps the built-in default ('high'). */
export const ClaudeOpusDefaultReasoningEffort = defineSetting<string>('chat.claudeOpusDefaultReasoningEffort', ConfigType.ExperimentBased, '');
/** Enable read_file tool for GPT-5.5 models */
export const EnableGpt55ReadFileTool = defineSetting<boolean>('chat.gpt55ReadFileTool.enabled', ConfigType.ExperimentBased, true);
export const EnableChatImageUpload = defineSetting<boolean>('chat.imageUpload.enabled', ConfigType.Simple, true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,12 @@ export class BaseTelemetryService implements ITelemetryService {
...Object.fromEntries(props),
...this._sharedProperties
};
// Mark the queried-feature name trusted so the telemetry cleaner does not redact the
// `/vscode/`-scoped key as a `user-file-path`.
const queriedFeature = properties['ABExp.queriedFeature'];
if (typeof queriedFeature === 'string') {
properties['ABExp.queriedFeature'] = new TelemetryTrustedValue(queriedFeature);
}
this._microsoftTelemetrySender.sendInternalTelemetryEvent(eventName, properties);
this._microsoftTelemetrySender.sendTelemetryEvent(eventName, properties);
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@
"tsec-compile-check": "node --max-old-space-size=8192 node_modules/tsec/bin/tsec -p src/tsconfig.tsec.json",
"vscode-dts-compile-check": "tsc --project src/tsconfig.vscode-dts.json && tsc --project src/tsconfig.vscode-proposed-dts.json",
"valid-layers-check": "node build/checker/layersChecker.ts && node build/checker/layersTypeCheck.ts",
"define-class-fields-check": "node build/lib/propertyInitOrderChecker.ts && tsc --project src/tsconfig.defineClassFields.json",
"define-class-fields-check": "node --max-old-space-size=8192 build/lib/propertyInitOrderChecker.ts && tsc --project src/tsconfig.defineClassFields.json",
"update-distro": "node build/npm/update-distro.ts",
"export-policy-data": "node build/lib/policies/exportPolicyData.ts",
"web": "echo 'npm run web' is replaced by './scripts/code-server' or './scripts/code-web'",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { ChatAIDisabledSettingId } from '../../chat/common/chatSettings.js';
import { IContextKeyService } from '../../contextkey/common/contextkey.js';
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
import { bindContextKey, observableConfigValue } from '../../observable/common/platformObservableUtils.js';
import { COPILOT_SANDBOX_ENABLED_KEY, IManagedSettingsService } from '../../policy/common/copilotManagedSettings.js';
import { COPILOT_SANDBOX_ALLOW_BYPASS_KEY, COPILOT_SANDBOX_ENABLED_KEY, IManagedSettingsService } from '../../policy/common/copilotManagedSettings.js';
import { AGENT_HOST_ENABLED_CONTEXT_KEY, IAgentHostEnablementService } from '../common/agentHostEnablementService.js';

export class AgentHostEnablementService extends Disposable implements IAgentHostEnablementService {
Expand All @@ -20,6 +20,7 @@ export class AgentHostEnablementService extends Disposable implements IAgentHost

readonly enabled: IObservable<boolean>;
readonly managedSandboxEnforced: IObservable<boolean>;
readonly managedSandboxAllowsBypass: IObservable<boolean>;

constructor(
private readonly _isAgentHostRuntimeAvailable: boolean,
Expand All @@ -35,6 +36,9 @@ export class AgentHostEnablementService extends Disposable implements IAgentHost
this.managedSandboxEnforced = observableFromEvent(this,
managedSettingsService.onDidChangeManagedSettings,
() => managedSettingsService.getManagedSettingValue(COPILOT_SANDBOX_ENABLED_KEY) === true);
this.managedSandboxAllowsBypass = observableFromEvent(this,
managedSettingsService.onDidChangeManagedSettings,
() => managedSettingsService.getManagedSettingValue(COPILOT_SANDBOX_ALLOW_BYPASS_KEY) === true);
}
}

Expand Down
45 changes: 44 additions & 1 deletion src/vs/platform/agentHost/browser/agentHostProtocolClient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ import { Schemas } from '../../../base/common/network.js';
import { hasKey } from '../../../base/common/types.js';
import { URI } from '../../../base/common/uri.js';
import { generateUuid } from '../../../base/common/uuid.js';
import { localize } from '../../../nls.js';
import { ILogService } from '../../log/common/log.js';
import { FileSystemProviderErrorCode, toFileSystemProviderErrorCode } from '../../files/common/files.js';
import { ConfigurationTarget, ConfigurationTargetToString, IConfigurationService } from '../../configuration/common/configuration.js';
import { AgentSession, IAgentCreateChatRequestOptions, IAgentCreateSessionConfig, IAgentResolveSessionConfigParams, IAgentSessionConfigCompletionsParams, IAgentSessionMetadata, AuthenticateParams, AuthenticateResult, IMcpNotification } from '../common/agent.js';
import { AGENT_HOST_DEBUG_LOGS_CHUNK_BYTES, AGENT_HOST_DEBUG_LOGS_MAX_ENTRIES, IAgentConnection, IAgentHostManagedSettingsDiagnostics, IAgentHostNetworkDiagnosticsInfo, IAgentHostNetworkFetchResult, type AgentHostDebugLogsArtifactKind, type IAgentHostDebugLogsArtifact, type IAgentHostDebugLogsChunk } from '../common/agentService.js';
import { ClaimAgentHostDetachedWorktreeExtensionMethod, CollectAgentHostDebugLogsExtensionMethod, CreateAgentHostDetachedWorktreeExtensionMethod, DeleteAgentHostDetachedWorktreeExtensionMethod, GetAgentHostSessionStateFileExtensionMethod, ReadAgentHostDebugLogsChunkExtensionMethod, ReconcileAgentHostDetachedWorktreesExtensionMethod, SetAgentHostDetachedWorktreeArchivedExtensionMethod, supportsAgentHostChatStateFile, type IAgentHostExtensionCommandMap, type IAgentHostExtensionInitializeResult } from '../common/agentHostExtensionProtocol.js';
import { ClaimAgentHostDetachedWorktreeExtensionMethod, CollectAgentHostDebugLogsExtensionMethod, CreateAgentHostDetachedWorktreeExtensionMethod, DeleteAgentHostDetachedWorktreeExtensionMethod, GetAgentHostSessionStateFileExtensionMethod, ReadAgentHostDebugLogsChunkExtensionMethod, ReconcileAgentHostDetachedWorktreesExtensionMethod, RequestAgentHostWorkspaceTrustExtensionMethod, SetAgentHostDetachedWorktreeArchivedExtensionMethod, supportsAgentHostChatStateFile, type IAgentHostExtensionCommandMap, type IAgentHostExtensionInitializeResult, type IAgentHostExtensionServerCommandMap } from '../common/agentHostExtensionProtocol.js';
import { AMBIENT_AGENT_HOST_AUTHORITY } from '../common/agentHostConnectionsService.js';
import { createRemoteWatchHandle, type IRemoteWatchHandle } from '../common/agentHostFileSystemProvider.js';
import { AgentSubscriptionManager, type IActiveSubscriptionInfo, type IAgentSubscription } from '../common/state/agentSubscription.js';
Expand Down Expand Up @@ -52,6 +53,8 @@ import { isFileResourceRead } from '../common/resourceReadLogging.js';
import { ResourceSet } from '../../../base/common/map.js';
import { computeReconnectDelay, DEFAULT_RECONNECT_POLICY, hasExhaustedReconnectAttempts, type IRemoteAgentHostReconnectPolicy } from '../common/reconnectPolicy.js';
import type { IRemoteAgentHostProtocolClient } from '../common/remoteAgentHostService.js';
import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from '../../workspace/common/workspaceTrust.js';
import { isWorktreeUnderRepository } from '../common/worktreePaths.js';

const AHP_CLIENT_CONNECTION_CLOSED = -32000;
// AHP 0.9 changed the automation catalog wire shape, so VS Code cannot safely negotiate 0.8.
Expand Down Expand Up @@ -400,6 +403,8 @@ export class AgentHostProtocolClient extends Disposable implements IAgentConnect
@IAgentHostResourceService private readonly _resourceService: IAgentHostResourceService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@ITelemetryService private readonly _telemetryService: ITelemetryService,
@IWorkspaceTrustManagementService private readonly _workspaceTrustManagementService: IWorkspaceTrustManagementService,
@IWorkspaceTrustRequestService private readonly _workspaceTrustRequestService: IWorkspaceTrustRequestService,
) {
super();
this._resourceIdentity = identity;
Expand Down Expand Up @@ -1951,6 +1956,44 @@ export class AgentHostProtocolClient extends Disposable implements IAgentConnect
void (async () => {
try {
switch (method) {
case RequestAgentHostWorkspaceTrustExtensionMethod: {
if (typeof p.workspace !== 'string') {
throw new Error('Missing workspace');
}
const hostWorkspace = URI.parse(p.workspace, true);
if (hostWorkspace.scheme !== Schemas.file || !hostWorkspace.path.startsWith('/')) {
throw new Error('Workspace must be an absolute file URI');
}
const workspace = this.resourceUris.fromAgentHost(hostWorkspace);
if (p.trustedParent !== undefined) {
if (typeof p.trustedParent !== 'string') {
throw new Error('Invalid trustedParent');
}
const hostParent = URI.parse(p.trustedParent, true);
if (hostParent.scheme !== Schemas.file || !hostParent.path.startsWith('/')) {
throw new Error('Trusted parent must be an absolute file URI');
}
if (!isWorktreeUnderRepository(hostWorkspace, hostParent)) {
throw new Error('Workspace is not a managed worktree under the trusted parent');
}
const parent = this.resourceUris.fromAgentHost(hostParent);
const parentTrust = await this._workspaceTrustManagementService.getUriTrustInfo(parent);
if (parentTrust.trusted) {
const workspaceTrust = await this._workspaceTrustManagementService.getUriTrustInfo(workspace);
if (!workspaceTrust.trusted) {
await this._workspaceTrustManagementService.setUrisTrust([workspace], true);
}
sendResult({ trusted: true } satisfies IAgentHostExtensionServerCommandMap[typeof RequestAgentHostWorkspaceTrustExtensionMethod]['result']);
return;
}
}
const trusted = await this._workspaceTrustRequestService.requestResourcesTrust({
uri: workspace,
message: localize('agentHost.trustWorkspaceMessage', "An agent session will be able to read files, run commands, and make changes in this folder."),
});
sendResult({ trusted: trusted === true } satisfies IAgentHostExtensionServerCommandMap[typeof RequestAgentHostWorkspaceTrustExtensionMethod]['result']);
return;
}
case 'resourceList': {
if (!p.uri) { throw new Error('Missing uri'); }
const result = await this._resourceService.list(identity, URI.parse(p.uri as string));
Expand Down
Loading
Loading