Path: blob/main/extensions/copilot/src/extension/agents/vscode-node/askAgentProvider.ts
13399 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import * as vscode from 'vscode';6import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';7import { AGENT_FILE_EXTENSION } from '../../../platform/customInstructions/common/promptTypes';8import { IVSCodeExtensionContext } from '../../../platform/extContext/common/extensionContext';9import { IFileSystemService } from '../../../platform/filesystem/common/fileSystemService';10import { ILogService } from '../../../platform/log/common/logService';11import { Disposable } from '../../../util/vs/base/common/lifecycle';12import { AgentConfig, buildAgentMarkdown, DEFAULT_READ_TOOLS } from './agentTypes';1314/**15* Base Ask agent configuration.16* The Ask agent is read-only: it answers questions, explains code, and17* provides information without modifying the workspace.18*/19const BASE_ASK_AGENT_CONFIG: AgentConfig = {20name: 'Ask',21description: 'Answers questions without making changes',22argumentHint: 'Ask a question about your code or project',23target: 'vscode',24disableModelInvocation: true,25agents: [],26tools: [27...DEFAULT_READ_TOOLS,28'vscode.mermaid-chat-features/renderMermaidDiagram',29],30body: '' // Generated dynamically in buildCustomizedConfig31};3233/**34* Provides the Ask agent dynamically with settings-based customization.35*36* The Ask agent is a read-only conversational mode for answering questions,37* explaining code, and researching topics without making any edits to the38* workspace. It uses an embedded configuration and generates .agent.md content39* with settings-based customization (additional tools and model override).40*/41export class AskAgentProvider extends Disposable implements vscode.ChatCustomAgentProvider {42readonly label = vscode.l10n.t('Ask Agent');4344private static readonly CACHE_DIR = 'ask-agent';45private static readonly AGENT_FILENAME = `Ask${AGENT_FILE_EXTENSION}`;4647private readonly _onDidChangeCustomAgents = this._register(new vscode.EventEmitter<void>());48readonly onDidChangeCustomAgents = this._onDidChangeCustomAgents.event;4950constructor(51@IConfigurationService private readonly _configurationService: IConfigurationService,52@IVSCodeExtensionContext private readonly _extensionContext: IVSCodeExtensionContext,53@IFileSystemService private readonly _fileSystemService: IFileSystemService,54@ILogService private readonly _logService: ILogService,55) {56super();5758this._register(this._configurationService.onDidChangeConfiguration(e => {59if (e.affectsConfiguration(ConfigKey.AskAgentAdditionalTools.fullyQualifiedId) ||60e.affectsConfiguration(ConfigKey.AskAgentModel.fullyQualifiedId)) {61this._onDidChangeCustomAgents.fire();62}63}));64}6566async provideCustomAgents(67_context: unknown,68_token: vscode.CancellationToken69): Promise<vscode.ChatResource[]> {70const config = this._buildCustomizedConfig();71const content = buildAgentMarkdown(config);72const fileUri = await this._writeCacheFile(content);73return [{ uri: fileUri }];74}7576private async _writeCacheFile(content: string): Promise<vscode.Uri> {77const cacheDir = vscode.Uri.joinPath(78this._extensionContext.globalStorageUri,79AskAgentProvider.CACHE_DIR80);8182try {83await this._fileSystemService.stat(cacheDir);84} catch {85await this._fileSystemService.createDirectory(cacheDir);86}8788const fileUri = vscode.Uri.joinPath(cacheDir, AskAgentProvider.AGENT_FILENAME);89await this._fileSystemService.writeFile(fileUri, new TextEncoder().encode(content));90this._logService.trace(`[AskAgentProvider] Wrote agent file: ${fileUri.toString()}`);91return fileUri;92}9394static buildAgentBody(): string {95return `You are an ASK AGENT — a knowledgeable assistant that answers questions, explains code, and provides information.9697Your job: understand the user's question → research the codebase as needed → provide a clear, thorough answer. You are strictly read-only: NEVER modify files or run commands that change state.9899<rules>100- NEVER use file editing tools, terminal commands that modify state, or any write operations101- Focus on answering questions, explaining concepts, and providing information102- Use search and read tools to gather context from the codebase when needed103- Provide code examples in your responses when helpful, but do NOT apply them104- Use #tool:vscode/askQuestions to clarify ambiguous questions before researching105- When the user's question is about code, reference specific files and symbols106- If a question would require making changes, explain what changes would be needed but do NOT make them107</rules>108109<capabilities>110You can help with:111- **Code explanation**: How does this code work? What does this function do?112- **Architecture questions**: How is the project structured? How do components interact?113- **Debugging guidance**: Why might this error occur? What could cause this behavior?114- **Best practices**: What's the recommended approach for X? How should I structure Y?115- **API and library questions**: How do I use this API? What does this method expect?116- **Codebase navigation**: Where is X defined? Where is Y used?117- **General programming**: Language features, algorithms, design patterns, etc.118</capabilities>119120<workflow>1211. **Understand** the question — identify what the user needs to know1222. **Research** the codebase if needed — use search and read tools to find relevant code1233. **Clarify** if the question is ambiguous — use #tool:vscode/askQuestions1244. **Answer** clearly — provide a well-structured response with references to relevant code125</workflow>`;126}127128private _buildCustomizedConfig(): AgentConfig {129const additionalTools = this._configurationService.getConfig(ConfigKey.AskAgentAdditionalTools);130const modelOverride = this._configurationService.getConfig(ConfigKey.AskAgentModel);131132// Collect tools to add133const toolsToAdd: string[] = [...additionalTools];134135// Always include askQuestions tool (now provided by core)136toolsToAdd.push('vscode/askQuestions');137138// Merge additional tools (deduplicated)139const tools = toolsToAdd.length > 0140? [...new Set([...BASE_ASK_AGENT_CONFIG.tools, ...toolsToAdd])]141: [...BASE_ASK_AGENT_CONFIG.tools];142143return {144...BASE_ASK_AGENT_CONFIG,145tools,146body: AskAgentProvider.buildAgentBody(),147...(modelOverride ? { model: modelOverride } : {}),148};149}150}151152153