1
>
/*---------------------------------------------------------------------------------------------
copilotCliConfig.ts
2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { localize } from '../../../nls.js';
7
>
import { createSchema, schemaProperty } from './agentHostSchema.js';
8
>
import type { ModelSelection } from './state/protocol/state.js';
9
>
10
>
/**
11
>
* Root-config keys consumed exclusively by the Copilot CLI provider
12
>
* (`CopilotSessionLauncher` / `CopilotAgent`) — kept out of the
13
>
* provider-agnostic `agentHostCustomizationConfigSchema`.
14
>
*/
15
>
export const enum CopilotCliConfigKey {
16
>
/** Use Agent Host's custom terminal tool instead of the SDK's default. Off by default. */
17
>
EnableCustomTerminalTool = 'enableCustomTerminalTool',
18
>
/** Log level passed to the Copilot SDK client. */
19
>
CopilotSdkLogLevel = 'copilotSdkLogLevel',
20
>
/** Enable the rubber duck critic subagent. */
21
>
RubberDuck = 'rubberDuck',
22
>
/** Apply Opus 4.8-tuned system-prompt overrides on Opus 4.8 models. Off by default. */
23
>
Opus48Prompt = 'opus48Prompt',
24
>
/** Enable runtime tool search (deferred-tool loading) for Copilot SDK sessions. Off by default. */
25
>
ToolSearchEnabled = 'toolSearchEnabled',
26
>
/** Override reasoning effort regardless of the picker value; unsupported values are ignored. */
27
>
ReasoningEffortOverride = 'reasoningEffortOverride',
28
>
/** Per-model capability overrides (family aliases) keyed by model id. */
29
>
ModelCapabilityOverrides = 'modelCapabilityOverrides',
30
>
}
31
>
32
>
// VS Code `chat.agentHost.*` setting IDs that feed the root-config keys above,
33
>
// kept beside the keys they forward to. Registered in `chat.shared.contribution.ts`
34
>
// and forwarded into the host's root config by `AgentHostCopilotCliSettingsContribution`
35
>
// (and, for the terminal-tool toggle, `AgentHostTerminalContribution`).
36
>
37
>
export const AgentHostCustomTerminalToolEnabledSettingId = 'chat.agentHost.customTerminalTool.enabled';
38
>
39
>
export const AgentHostCopilotSdkLogLevelSettingId = 'chat.agentHost.copilotSdk.logLevel';
40
>
41
>
export const AgentHostOpus48PromptEnabledSettingId = 'chat.agentHost.opus48Prompt.enabled';
42
>
43
>
export const AgentHostToolSearchEnabledSettingId = 'chat.agentHost.copilot.toolSearch.enabled';
44
>
45
>
export const AgentHostReasoningEffortOverrideSettingId = 'chat.agentHost.reasoningEffortOverride';
46
>
47
>
export const AgentHostModelCapabilityOverridesSettingId = 'chat.agentHost.modelCapabilityOverrides';
48
>
49
>
export const copilotSdkLogLevelSettingValues = ['info', 'trace'] as const;
50
>
export type CopilotSdkLogLevelSetting = typeof copilotSdkLogLevelSettingValues[number];
51
>
52
>
/** Per-model capability override; the agent-host equivalent of the extension's `IModelCapabilityOverride`. */
53
>
interface ICopilotCliModelCapabilityOverride {
54
>
/** Alias the model's family for prompt/capability routing (e.g. `"claude-opus-4-8"`). */
55
>
readonly family?: string;
56
>
}
57
>
58
>
/** Map of model id → capability override. */
59
>
export type CopilotCliModelCapabilityOverrides = Record<string, ICopilotCliModelCapabilityOverride>;
60
>
61
>
export const copilotCliConfigSchema = createSchema({
62
>
[CopilotCliConfigKey.EnableCustomTerminalTool]: schemaProperty<boolean>({
63
>
type: 'boolean',
64
>
title: localize('agentHost.config.enableCustomTerminalTool.title', "Use Agent Host Terminal Tool"),
65
>
description: localize('agentHost.config.enableCustomTerminalTool.description', "When enabled, Copilot SDK sessions use Agent Host's terminal tool override instead of the SDK's default terminal behavior."),
66
>
default: false,
67
>
}),
68
>
[CopilotCliConfigKey.CopilotSdkLogLevel]: schemaProperty<CopilotSdkLogLevelSetting>({
69
>
type: 'string',
70
>
title: localize('agentHost.config.copilotSdkLogLevel.title', "Copilot SDK Log Level"),
71
>
description: localize('agentHost.config.copilotSdkLogLevel.description', "Controls logging from the Copilot SDK runtime. Agent host trace logging always enables trace output."),
72
>
enum: [...copilotSdkLogLevelSettingValues],
73
>
enumLabels: [
74
>
localize('agentHost.config.copilotSdkLogLevel.info', "Info"),
75
>
localize('agentHost.config.copilotSdkLogLevel.trace', "Trace"),
76
>
],
77
>
default: 'info',
78
>
}),
79
>
[CopilotCliConfigKey.RubberDuck]: schemaProperty<boolean>({
80
>
type: 'boolean',
81
>
title: localize('agentHost.config.rubberDuck.title', "Rubber Duck Agent"),
82
>
description: localize('agentHost.config.rubberDuck.description', "When enabled, the coding agent uses a rubber duck critic subagent to review code changes using a complementary model."),
83
>
default: false,
84
>
}),
85
>
[CopilotCliConfigKey.Opus48Prompt]: schemaProperty<boolean>({
86
>
type: 'boolean',
87
>
title: localize('agentHost.config.opus48Prompt.title', "Opus 4.8 Agent Prompt"),
88
>
description: localize('agentHost.config.opus48Prompt.description', "When enabled, Copilot SDK sessions running a Claude Opus 4.8 model apply Opus 4.8-tuned system-prompt section overrides on top of the default system message."),
89
>
default: false,
90
>
}),
91
>
[CopilotCliConfigKey.ToolSearchEnabled]: schemaProperty<boolean>({
92
>
type: 'boolean',
93
>
title: localize('agentHost.config.toolSearchEnabled.title', "Agent Host Tool Search"),
94
>
description: localize('agentHost.config.toolSearchEnabled.description', "When enabled, Copilot SDK sessions defer MCP and non-core VS Code tools behind a tool-search tool so the model discovers them on demand instead of loading every tool definition up front."),
95
>
default: false,
96
>
}),
97
>
[CopilotCliConfigKey.ReasoningEffortOverride]: schemaProperty<string>({
98
>
type: 'string',
99
>
title: localize('agentHost.config.reasoningEffortOverride.title', "Reasoning Effort Override"),
100
>
description: localize('agentHost.config.reasoningEffortOverride.description', "Overrides the reasoning effort for Copilot SDK sessions regardless of the per-model picker value. Set it to a level the selected model supports (e.g. `low`, `medium`, `high`, `xhigh`); a value that isn't a recognized effort level is ignored and the session falls back to the picker value. Only affects Copilot SDK sessions; intended for experimentation."),
101
>
default: '',
102
>
}),
103
>
[CopilotCliConfigKey.ModelCapabilityOverrides]: schemaProperty<CopilotCliModelCapabilityOverrides>({
104
>
type: 'object',
105
>
title: localize('agentHost.config.modelCapabilityOverrides.title', "Model Capability Overrides"),
106
>
description: localize('agentHost.config.modelCapabilityOverrides.description', "Per-model capability overrides for Copilot SDK sessions, keyed by model id. Aliasing a model id to a known `family` routes it to that family's tuned system prompt without changing the model id sent to the runtime. Only affects Copilot SDK sessions; intended for experimentation."),
107
>
additionalProperties: {
108
>
type: 'object',
109
>
title: localize('agentHost.config.modelCapabilityOverrides.entry.title', "Capability Override"),
110
>
description: localize('agentHost.config.modelCapabilityOverrides.entry.description', "A single capability override. The property key is the model id."),
111
>
properties: {
112
>
family: {
113
>
type: 'string',
114
>
title: localize('agentHost.config.modelCapabilityOverrides.family.title', "Family"),
115
>
description: localize('agentHost.config.modelCapabilityOverrides.family.description', "Alias the model's family for prompt/capability routing (e.g. `claude-opus-4-8`)."),
116
>
},
117
>
},
118
>
},
119
>
default: {},
120
>
}),
121
>
});
122
>
123
>
/** Returns the configured family alias for `modelId`, or `undefined`. Malformed entries are treated as unset. */
124
function getModelFamilyAlias(overrides: CopilotCliModelCapabilityOverrides | undefined, modelId: string): string | undefined {
125
const family = overrides?.[modelId]?.family;
126
return typeof family === 'string' && family.length > 0 ? family : undefined;
127
}
129
>
/**
130
>
* Substitutes a configured family alias for the model id so an aliased preview model
131
>
* routes to a known family's prompt contributor. `model.config` picker values are
132
>
* preserved; returns the input unchanged when no alias applies.
133
>
*/
134
>
export function applyModelFamilyAlias(model: ModelSelection | undefined, overrides: CopilotCliModelCapabilityOverrides | undefined): ModelSelection | undefined {
135
if (!model) {
136
return undefined;