Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
d223582
chat: add a render-only Permissions area to the Customizations editor
joshspicer Aug 18, 2026
e1b2f43
chat: cross-reference the managed rule builder from the display parser
joshspicer Aug 18, 2026
3faaf67
chat: align the Permissions sections with the customization design la…
joshspicer Aug 18, 2026
8e19e99
chat: fix staleness, partial provider failures and focus in the Permi…
joshspicer Aug 19, 2026
37697d4
chat: add a Permissions section fixture and polish its states
joshspicer Aug 19, 2026
1553b6d
chat: complete the Permissions fixture coverage
joshspicer Aug 19, 2026
f7dfaeb
chat: render managed permissions from VS Code's own channels while th…
joshspicer Aug 19, 2026
cceb427
sessions: fix unified workspace picker edge cases (#337095)
meganrogge Sep 21, 2026
2c261bc
Update CodeNotify for automations (#337118)
benvillalobos Sep 21, 2026
03afce5
test: isolate CopilotAgent proxy environment (#337119)
jruales Sep 21, 2026
4a613ca
[cherry-pick] sessions: make harness bootstrap authentication provide…
vs-code-engineering[bot] Sep 21, 2026
e3ada48
chat: Configure keybindings for voice control actions (#337115)
meganrogge Sep 21, 2026
62a4595
Revert CSS changes from PR #336770 to fix hover regression (#337107)
lszomoru Sep 21, 2026
36351b5
network: align URL trust and IDN domain policies (#336960)
dmitrivMS Sep 21, 2026
20a1919
agentHost: stabilize concurrent subagent replay (#337102)
roblourens Sep 21, 2026
b112ecc
Make subagent model guidance the default (#337116)
bhavyaus Sep 21, 2026
5188ead
Fix migration activity persistence after reverting a customization (#…
hawkticehurst Sep 21, 2026
d046fe7
Agents - remember isolation per workspace (#337125)
lszomoru Sep 21, 2026
8f2902d
sessions: cap unified picker recent folders (#337132)
meganrogge Sep 21, 2026
bf715be
test: clean up Windows agent-host descendants after shutdown (#337080)
chrmarti Sep 21, 2026
d95c2e7
sessions: fix unified workspace picker edge cases (#337095)
meganrogge Sep 21, 2026
10f7c9f
Update CodeNotify for automations (#337118)
benvillalobos Sep 21, 2026
1a77f62
test: isolate CopilotAgent proxy environment (#337119)
jruales Sep 21, 2026
6c57b19
[cherry-pick] sessions: make harness bootstrap authentication provide…
vs-code-engineering[bot] Sep 21, 2026
eaa9f44
chat: Configure keybindings for voice control actions (#337115)
meganrogge Sep 21, 2026
a3be23d
Revert CSS changes from PR #336770 to fix hover regression (#337107)
lszomoru Sep 21, 2026
60dd258
network: align URL trust and IDN domain policies (#336960)
dmitrivMS Sep 21, 2026
ca69ecb
agentHost: stabilize concurrent subagent replay (#337102)
roblourens Sep 21, 2026
260a659
Make subagent model guidance the default (#337116)
bhavyaus Sep 21, 2026
e638883
Fix migration activity persistence after reverting a customization (#…
hawkticehurst Sep 21, 2026
beebed3
Agents - remember isolation per workspace (#337125)
lszomoru Sep 21, 2026
7e49092
sessions: cap unified picker recent folders (#337132)
meganrogge Sep 21, 2026
2f7cc34
test: clean up Windows agent-host descendants after shutdown (#337080)
chrmarti Sep 21, 2026
a52e1c4
Merge branch 'agents/managed-settings-ui-enhancement' into main+
homecoc Sep 21, 2026
df0108f
Merge branch 'main+' of https://github.com/homecoc/ticode into main+
homecoc Sep 21, 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
16 changes: 8 additions & 8 deletions .github/CODENOTIFY
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@ src/vs/base/browser/ui/tree/** @benibenj

# Platform
src/vs/platform/agentHost/node/claude/** @TylerLeonhardt
src/vs/platform/agentHost/**/*Automation* @ulugbekna
src/vs/platform/agentHost/**/*automation* @ulugbekna
src/vs/platform/agentHost/common/state/protocol/channels-automation-run/** @ulugbekna
src/vs/platform/agentHost/common/state/protocol/channels-automation/** @ulugbekna
src/vs/platform/agentHost/**/*Automation* @ulugbekna @benvillalobos
src/vs/platform/agentHost/**/*automation* @ulugbekna @benvillalobos
src/vs/platform/agentHost/common/state/protocol/channels-automation-run/** @ulugbekna @benvillalobos
src/vs/platform/agentHost/common/state/protocol/channels-automation/** @ulugbekna @benvillalobos
src/vs/platform/browserView/** @kycutler @jruales
src/vs/platform/quickinput/** @TylerLeonhardt
src/vs/platform/secrets/** @TylerLeonhardt
Expand All @@ -42,12 +42,12 @@ src/vs/workbench/services/views/** @sandy081 @benibenj
# Workbench Contributions
src/vs/workbench/contrib/authentication/** @TylerLeonhardt
src/vs/workbench/contrib/browserView/** @kycutler @jruales
src/vs/workbench/contrib/chat/**/*Automation* @ulugbekna
src/vs/workbench/contrib/chat/**/*automation* @ulugbekna
src/vs/workbench/contrib/chat/**/*Automation* @ulugbekna @benvillalobos
src/vs/workbench/contrib/chat/**/*automation* @ulugbekna @benvillalobos
src/vs/workbench/contrib/chat/browser/chatListRenderer.ts @roblourens
src/vs/workbench/contrib/chat/common/automations/** @ulugbekna
src/vs/workbench/contrib/chat/common/automations/** @ulugbekna @benvillalobos
src/vs/workbench/contrib/chat/electron-browser/builtInTools/fetchPageTool.ts @TylerLeonhardt
src/vs/workbench/contrib/chat/test/common/automations/** @ulugbekna
src/vs/workbench/contrib/chat/test/common/automations/** @ulugbekna @benvillalobos
src/vs/workbench/contrib/localization/** @TylerLeonhardt
src/vs/workbench/contrib/quickaccess/browser/commandsQuickAccess.ts @TylerLeonhardt
src/vs/workbench/contrib/scm/** @lszomoru
Expand Down
61 changes: 61 additions & 0 deletions .github/instructions/ai-customization.instructions.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,67 @@ Themed icons using `registerIcon(id, codicon, label)`:

**Registration:** Import `./aiCustomization/aiCustomization.contribution.js` in `chat.contribution.ts`

## Permissions Area

The management editor's sidebar has two groups: `CUSTOMIZATIONS` (what shapes the agent) and
`PERMISSIONS` (what governs it). The permissions group is gated by
`chat.customizations.permissions.enabled` (default `false`) and contributes three sections —
Terminal, Files and Network.

### Render-only contract

**The Copilot runtime is the source of truth for permissions.** It owns the rule DSL, the matcher,
and the precedence between managed policy, configured rules, location grants and session grants.
Everything under `browser/aiCustomization/permissions/` and `common/permissions/` exists to
*display* the provenance the runtime reports.

Consequently:

- No code here decides whether an operation is permitted, and none of it re-implements matching.
- `chatPermissionRuleSyntax.ts` only splits `Kind(argument)` for display; it must never drive a
decision.
- Domains exist only for the rule families the runtime accepts — `Shell`/`Bash`/`PowerShell`,
`Read`, `Edit`/`Write`, `Domain`. MCP servers and built-in tools are governed by different
contracts and deliberately have no domain until the runtime can report rules for them.

### Files

```
common/permissions/
├── chatPermissions.ts # Rule, scope, effect, ceiling and snapshot types
├── chatPermissionRuleSyntax.ts # Display-only rule splitting
└── chatPermissionSnapshotService.ts # Provider interface

browser/permissions/
└── chatPermissionSnapshotService.ts # Current implementation (managed scope only)

browser/aiCustomization/permissions/
├── chatPermissionDomainRegistry.ts # IChatPermissionDomain + registry
├── chatPermissionDomains.ts # The Terminal / Files / Network domains
├── chatPermissionsSectionWidget.ts # One generic widget for any domain
├── chatPermissions.contribution.ts # Registers the sections
└── media/chatPermissions.css
```

### Snapshot states

`ChatPermissionSnapshot` is `loading | unavailable | error | available`. `unavailable` is a distinct
state on purpose: rendering an empty rule list when the runtime was never consulted would assert
"nothing governs this agent", which is the opposite of the truth in a fail-closed enterprise
deployment. For the same reason, an `available` snapshot carries `resolvedScopes`, and the widget
names the layers it could not read rather than omitting them silently.

The runtime currently exposes no read API for its full effective rule set — only the managed slice,
via the managed-settings diagnostics probe. `browser/permissions/chatPermissionSnapshotService.ts`
therefore reports only `ChatPermissionScope.Managed`. When the runtime gains an
effective-permissions projection, **that file is the only thing that changes**.

### Adding a domain

Add an entry to `CHAT_PERMISSION_DOMAINS` and a section id to
`AICustomizationManagementSection` / `AI_CUSTOMIZATION_PERMISSION_SECTIONS`. The section widget is
generic, so no UI changes are required.

---

*Update this file when making architectural changes to the AI Customization view.*
20 changes: 20 additions & 0 deletions .github/skills/policy-and-managed-settings/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,26 @@ General rules:
- The VS Code settings-to-managed-settings bridge is a compatibility path for legacy settings only. Do not add a new VS Code setting in order to bridge it; define new runtime-owned controls directly in the managed-settings/SDK contract. A temporary, false-by-default compatibility gate for the bridge itself is allowed; it is not a runtime control and must not become a template for new mapped settings.
- Run `npm run export-policy-data` for every VS Code or extension policy change. Never edit `build/lib/policies/policyData.jsonc` manually.

## Displaying Permissions in a Client

A client may *render* enterprise permission state, but never re-derive it. The runtime owns the rule
DSL, the matcher, and the precedence between managed policy, configured rules, location grants and
session grants; a client that reconstructs any of that becomes a second authority that silently
diverges.

Rules for a permission-rendering surface:

- Display the provenance the runtime reports. Do not compute precedence or shadowing client-side.
- Parsing is limited to splitting a rule into its displayable parts. It must not drive a decision.
- Distinguish "no rules" from "not known". When a layer could not be read, say so; an empty list
asserts that nothing governs the agent, which is the opposite of the truth under `failClosed`.
- When managed allowlists are intersected (`permissionsAllowIntersected`), the runtime omits the
resolved allow list. Explain that rather than showing an empty allow group.

VS Code's implementation lives in `chat/common/permissions/` and
`chat/browser/aiCustomization/permissions/`; see the AI Customization instructions for its
structure.

## Deprecated and Historical Channels

Some policy channels remain supported for existing controls but are closed to new properties:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -848,9 +848,9 @@ describe('ExP Service scoped treatment resolution', () => {
const delegate = service.delegates[0];

// The new assignments endpoint returns the key with a `/vscode/` scope prefix only.
delegate.setTreatment('/vscode/config.chat.copilot.subagentModelGuidance.enabled', true);
delegate.setTreatment('/vscode/config.test.scopedTreatment', true);

expect(service.getTreatmentVariable<boolean>('config.chat.copilot.subagentModelGuidance.enabled')).toBe(true);
expect(service.getTreatmentVariable<boolean>('config.test.scopedTreatment')).toBe(true);

service.dispose();
});
Expand Down
5 changes: 3 additions & 2 deletions extensions/git/src/cloneManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,9 +211,10 @@ export class CloneManager {
}

private async tryOpenExistingRepository(cachedRepository: RepositoryCacheInfo[], url: string, postCloneAction?: ApiPostCloneAction, parentPath?: string, ref?: string, returnRepositoryPath?: boolean): Promise<string | undefined> {
// Gather existing folders/workspace files (ignore ones that no longer exist)
// Ignore cached entries whose requested path no longer exists.
const existingCachedRepositories: RepositoryCacheInfo[] = (await Promise.all<RepositoryCacheInfo | undefined>(cachedRepository.map(async folder => {
const stat = await fs.promises.stat(folder.workspacePath).catch(() => undefined);
const cachedPath = returnRepositoryPath ? folder.repositoryPath : folder.workspacePath;
const stat = await fs.promises.stat(cachedPath).catch(() => undefined);
if (stat) {
return folder;
}
Expand Down
49 changes: 49 additions & 0 deletions extensions/git/src/test/cloneManager.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import 'mocha';
import * as assert from 'assert';
import * as fs from 'fs';
import * as os from 'os';
import * as path from 'path';
import { CloneManager } from '../cloneManager';
import type { RepositoryCacheInfo } from '../repositoryCache';

interface ICloneManagerHarness {
cloneRepository(url: string, parentPath?: string): Promise<string | undefined>;
}

const tryOpenExistingRepository = Reflect.get(CloneManager.prototype, 'tryOpenExistingRepository') as (
this: ICloneManagerHarness,
cachedRepository: RepositoryCacheInfo[],
url: string,
postCloneAction?: 'none',
parentPath?: string,
ref?: string,
returnRepositoryPath?: boolean,
) => Promise<string | undefined>;

suite('CloneManager', () => {
test('clones again when a cached repository path was deleted', async () => {
const workspacePath = await fs.promises.mkdtemp(path.join(os.tmpdir(), 'vscode-git-clone-manager-'));
const repositoryPath = path.join(workspacePath, 'deleted-repository');
const calls: { url: string; parentPath: string | undefined }[] = [];
try {
const result = await tryOpenExistingRepository.call({
cloneRepository: async (url, parentPath) => {
calls.push({ url, parentPath });
return '/repos/recloned';
},
}, [{ workspacePath, repositoryPath }], 'https://github.com/microsoft/vscode.git', 'none', '/repos', undefined, true);

assert.deepStrictEqual({ result, calls }, {
result: '/repos/recloned',
calls: [{ url: 'https://github.com/microsoft/vscode.git', parentPath: '/repos' }],
});
} finally {
await fs.promises.rm(workspacePath, { recursive: true, force: true });
}
});
});
7 changes: 4 additions & 3 deletions src/vs/base/common/uri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -707,15 +707,16 @@ function _asFormatted(uri: URI, skipEncoding: boolean): string {
}
}
if (path) {
// lower-case windows drive letters in /C:/fff or C:/fff
// HTTP paths are case-sensitive, even when their first segment resembles a drive letter.
const lowerScheme = scheme.toLowerCase();
if (path.length >= 3 && path.charCodeAt(0) === CharCode.Slash && path.charCodeAt(2) === CharCode.Colon) {
const code = path.charCodeAt(1);
if (code >= CharCode.A && code <= CharCode.Z) {
if (code >= CharCode.A && code <= CharCode.Z && lowerScheme !== 'http' && lowerScheme !== 'https') {
path = `/${String.fromCharCode(code + 32)}:${path.substr(3)}`; // "/c:".length === 3
}
} else if (path.length >= 2 && path.charCodeAt(1) === CharCode.Colon) {
const code = path.charCodeAt(0);
if (code >= CharCode.A && code <= CharCode.Z) {
if (code >= CharCode.A && code <= CharCode.Z && lowerScheme !== 'http' && lowerScheme !== 'https') {
path = `${String.fromCharCode(code + 32)}:${path.substr(2)}`; // "/c:".length === 3
}
}
Expand Down
20 changes: 20 additions & 0 deletions src/vs/base/test/common/uri.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,26 @@ suite('URI', () => {
assert.strictEqual(URI.parse('untitled:C:/Users/jrieken/Code/abc.txt').toString(), 'untitled:c%3A/Users/jrieken/Code/abc.txt');
});

test('URI#toString preserves drive-like HTTP path case', () => {
const schemes = ['http', 'https', 'HtTp', 'HTTPS'];
assert.deepStrictEqual(schemes.map(scheme => {
const uri = URI.parse(`${scheme}://example.test/C:/Secret`);
return [uri.toString(), uri.toString(true), URI.parse(uri.toString()).toString(true)];
}), schemes.map(scheme => [
`${scheme}://example.test/C%3A/Secret`,
`${scheme}://example.test/C:/Secret`,
`${scheme}://example.test/C:/Secret`,
]));
});

test('URI#toString retains non-HTTP drive-letter normalization', () => {
const schemes = ['file', 'untitled', 'vscode-remote', 'custom'];
assert.deepStrictEqual(
schemes.map(scheme => URI.parse(`${scheme}://server/C:/Secret`).toString(true)),
schemes.map(scheme => `${scheme}://server/c:/Secret`),
);
});

test('URI#toString, escape all the bits', () => {

const value = URI.file('/Users/jrieken/Code/_samples/18500/Mödel + Other Thîngß/model.js');
Expand Down
10 changes: 0 additions & 10 deletions src/vs/platform/agentHost/common/copilotCliConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,6 @@ export const enum CopilotCliConfigKey {
SkillCharBudget = 'skillCharBudget',
/** Override Auto's "Optimize for" preference. */
AutoModeTierOverride = 'autoModeTierOverride',
/** Tell the model to keep subagents on their default model unless the user asks otherwise. Off by default. */
SubagentModelGuidance = 'subagentModelGuidance',
/** Per-model capability overrides (family aliases) keyed by model id. */
ModelCapabilityOverrides = 'modelCapabilityOverrides',
}
Expand Down Expand Up @@ -71,8 +69,6 @@ export const CopilotSkillCharBudgetSettingId = 'chat.copilot.skillCharBudget';

export const CopilotAutoModeTierOverrideSettingId = 'github.copilot.chat.autoModeTierOverride';

export const CopilotSubagentModelGuidanceEnabledSettingId = 'chat.copilot.subagentModelGuidance.enabled';

export const AgentHostModelCapabilityOverridesSettingId = 'chat.agentHost.modelCapabilityOverrides';
export const AgentHostCopilotModelCapabilityOverridesSettingId = 'chat.agentHost.copilot.modelCapabilityOverrides';

Expand Down Expand Up @@ -216,12 +212,6 @@ export const copilotCliConfigSchema = createSchema({
description: localize('agentHost.config.autoModeTierOverride.description', "Overrides Auto's \"Optimize for\" preference. Accepts efficiency, balance, or intelligence. Applied when a session is created or resumed and when its model changes. Empty or unsupported values use the picker or service defaults."),
default: '',
}),
[CopilotCliConfigKey.SubagentModelGuidance]: schemaProperty<boolean>({
type: 'boolean',
title: localize('agentHost.config.subagentModelGuidance.title', "Subagent Model Guidance"),
description: localize('agentHost.config.subagentModelGuidance.description', "When enabled, Copilot SDK sessions instruct the model to keep subagents on their default model unless the user explicitly names another one."),
default: false,
}),
[CopilotCliConfigKey.ModelCapabilityOverrides]: schemaProperty<CopilotCliModelCapabilityOverrides>({
type: 'object',
title: localize('agentHost.config.modelCapabilityOverrides.title', "Model Capability Overrides"),
Expand Down
2 changes: 1 addition & 1 deletion src/vs/platform/agentHost/node/copilot/prompts/AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This directory customizes the system prompt for Copilot CLI **agent host** (ahp+

- `promptRegistry.ts` — `AgentHostPromptRegistry`: resolves the final `SystemMessageConfig` for a session's model. Defines the `IAgentHostPrompt` contributor interface and the `IAgentHostPromptContext` read-time context.
- `systemMessage.ts` — the default message (`COPILOT_AGENT_HOST_SYSTEM_MESSAGE`), shared identity text, the `fullSystemPrompt` / `sectionOverrides` builders, and `describeSystemMessageConfig` (the one-line log summary).
- `toolInstructions.ts` — the model-agnostic `tool_instructions` layer: gated or unconditional nudges (`TOOL_INSTRUCTION_LINES`) composed into the SDK's `tool_instructions` section, including the setting-gated default-model guidance for subagents (`chat.copilot.subagentModelGuidance.enabled`).
- `toolInstructions.ts` — the model-agnostic `tool_instructions` layer: gated or unconditional nudges (`TOOL_INSTRUCTION_LINES`) composed into the SDK's `tool_instructions` section, including the default-model guidance for subagents.
- `anthropicPrompt.ts` — example per-model contributor (Claude Opus 4.8).
- `allPrompts.ts` — side-effect import hub; importing it registers every contributor into the shared `agentHostPromptRegistry`.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { SectionOverride } from '@github/copilot-sdk';
import { coalesce } from '../../../../../base/common/arrays.js';
import { BrowserChatToolReferenceName, browserChatToolReferenceNames } from '../../../../browserView/common/browserChatToolReferenceNames.js';
import type { SchemaValue } from '../../../common/agentHostSchema.js';
import { CopilotCliConfigKey, copilotCliConfigSchema } from '../../../common/copilotCliConfig.js';
import { copilotCliConfigSchema } from '../../../common/copilotCliConfig.js';
import { CLIENT_TOOL_SEARCH_REFERENCE_NAME } from '../../../common/toolSearchConstants.js';

/**
Expand All @@ -24,8 +24,7 @@ import { CLIENT_TOOL_SEARCH_REFERENCE_NAME } from '../../../common/toolSearchCon
* To add guidance, write a {@link ToolInstructionLine} and add it to
* {@link TOOL_INSTRUCTION_LINES}. The browser guidance
* ({@link browserToolInstructions}) demonstrates a line gated on
* `openBrowserPage` plus an agentic browser tool; the subagent guidance
* ({@link subagentToolInstructions}) one gated on a setting.
* `openBrowserPage` plus an agentic browser tool.
*/

type CopilotCliConfigDefinition = typeof copilotCliConfigSchema.definition;
Expand Down Expand Up @@ -66,9 +65,7 @@ export const COPILOT_AGENT_HOST_SUBAGENT_TOOL_INSTRUCTIONS = [
'When launching subagents with the task tool, leave the `model`, `reasoning_effort`, and `context_tier` parameters unset — each agent type already runs on a model suited to it, and overriding the model changes the session\'s cost and behavior profile.',
'Only set the task tool\'s `model` parameter when the user explicitly names the model the subagent should run on.',
].join('\n');
/** Opt-in via {@link CopilotCliConfigKey.SubagentModelGuidance}. */
const subagentToolInstructions: ToolInstructionLine = ({ getSetting }) =>
getSetting(CopilotCliConfigKey.SubagentModelGuidance) === true ? COPILOT_AGENT_HOST_SUBAGENT_TOOL_INSTRUCTIONS : undefined;
const subagentToolInstructions: ToolInstructionLine = () => COPILOT_AGENT_HOST_SUBAGENT_TOOL_INSTRUCTIONS;

/**
* Front-end guidance for the integrated browser tools, ported from the Copilot
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ suite('AgentHostPromptRegistry', () => {
ensureNoDisposablesAreLeakedInTestSuite();

const LARGE_OUTPUT_LINE = COPILOT_AGENT_HOST_LARGE_OUTPUT_TOOL_INSTRUCTION;
const UNCONDITIONAL_TOOL_INSTRUCTIONS = LARGE_OUTPUT_LINE;
const UNCONDITIONAL_TOOL_INSTRUCTIONS = `${LARGE_OUTPUT_LINE}\n${COPILOT_AGENT_HOST_SUBAGENT_TOOL_INSTRUCTIONS}`;

const withUniversalAgentHostInstructions = (config: SystemMessageConfig): SystemMessageConfig => {
const configWithToolInstructions = config.mode === 'replace'
Expand Down Expand Up @@ -308,26 +308,6 @@ suite('AgentHostPromptRegistry', () => {
assert.deepStrictEqual(registry.resolveSystemMessageConfig({ id: 'm' }, context({}, ['anyTool'])), withUniversalAgentHostInstructions(COPILOT_AGENT_HOST_SYSTEM_MESSAGE));
});

test('layers the subagent model guidance only when its setting is enabled', () => {
const registry = new AgentHostPromptRegistry();
assert.deepStrictEqual(
[
registry.resolveSystemMessageConfig({ id: 'm' }, context({ [CopilotCliConfigKey.SubagentModelGuidance]: true })),
registry.resolveSystemMessageConfig({ id: 'm' }, context({ [CopilotCliConfigKey.SubagentModelGuidance]: false })),
],
[
withUniversalAgentHostInstructions({
mode: 'customize',
sections: {
identity: COPILOT_AGENT_HOST_SYSTEM_MESSAGE.sections.identity,
tool_instructions: { action: 'append', content: `\n${UNCONDITIONAL_TOOL_INSTRUCTIONS}\n${COPILOT_AGENT_HOST_SUBAGENT_TOOL_INSTRUCTIONS}` },
},
}),
withUniversalAgentHostInstructions(COPILOT_AGENT_HOST_SYSTEM_MESSAGE),
]
);
});

test('layers the browser tool_instructions onto the default config when browser tools are present', () => {
const registry = new AgentHostPromptRegistry();
assert.deepStrictEqual(
Expand Down
Loading
Loading