Path: blob/main/extensions/copilot/src/extension/agents/vscode-node/exploreAgentProvider.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* Fallback model priority list for the Explore agent.16* Passed as a YAML array; the runtime picks the first available model.17*/18const EXPLORE_AGENT_FALLBACK_MODELS: readonly string[] = [19'Claude Haiku 4.5 (copilot)',20'Gemini 3 Flash (Preview) (copilot)',21'Auto (copilot)',22];2324/**25* Base Explore agent configuration.26* The Explore agent is a read-only code research subagent that autonomously27* digs through codebases using multiple search strategies.28*/29const BASE_EXPLORE_AGENT_CONFIG: AgentConfig = {30name: 'Explore',31description: 'Fast read-only codebase exploration and Q&A subagent. Prefer over manually chaining multiple search and file-reading operations to avoid cluttering the main conversation. Safe to call in parallel. Specify thoroughness: quick, medium, or thorough.',32argumentHint: 'Describe WHAT you\'re looking for and desired thoroughness (quick/medium/thorough)',33target: 'vscode',34userInvocable: false,35agents: [],36tools: [37...DEFAULT_READ_TOOLS,38],39body: '' // Generated dynamically in buildCustomizedConfig40};4142/**43* Provides the Explore agent dynamically with settings-based customization.44*45* The Explore agent is a read-only code research subagent designed to be46* invoked by other agents (e.g., Plan) for autonomous codebase exploration.47* It uses small/fast models by default and focuses on search-heavy workflows.48*/49export class ExploreAgentProvider extends Disposable implements vscode.ChatCustomAgentProvider {50readonly label = vscode.l10n.t('Explore Agent');5152private static readonly CACHE_DIR = 'explore-agent';53private static readonly AGENT_FILENAME = `Explore${AGENT_FILE_EXTENSION}`;5455private readonly _onDidChangeCustomAgents = this._register(new vscode.EventEmitter<void>());56readonly onDidChangeCustomAgents = this._onDidChangeCustomAgents.event;5758constructor(59@IConfigurationService private readonly _configurationService: IConfigurationService,60@IVSCodeExtensionContext private readonly _extensionContext: IVSCodeExtensionContext,61@IFileSystemService private readonly _fileSystemService: IFileSystemService,62@ILogService private readonly _logService: ILogService,63) {64super();6566this._register(this._configurationService.onDidChangeConfiguration(e => {67if (e.affectsConfiguration('chat.exploreAgent.defaultModel') ||68e.affectsConfiguration(ConfigKey.ExploreAgentModel.fullyQualifiedId)) {69this._onDidChangeCustomAgents.fire();70}71}));72}7374async provideCustomAgents(75_context: unknown,76_token: vscode.CancellationToken77): Promise<vscode.ChatResource[]> {78const config = this._buildCustomizedConfig();79const content = buildAgentMarkdown(config);80const fileUri = await this._writeCacheFile(content);81return [{ uri: fileUri }];82}8384private async _writeCacheFile(content: string): Promise<vscode.Uri> {85const cacheDir = vscode.Uri.joinPath(86this._extensionContext.globalStorageUri,87ExploreAgentProvider.CACHE_DIR88);8990try {91await this._fileSystemService.stat(cacheDir);92} catch {93await this._fileSystemService.createDirectory(cacheDir);94}9596const fileUri = vscode.Uri.joinPath(cacheDir, ExploreAgentProvider.AGENT_FILENAME);97await this._fileSystemService.writeFile(fileUri, new TextEncoder().encode(content));98this._logService.trace(`[ExploreAgentProvider] Wrote agent file: ${fileUri.toString()}`);99return fileUri;100}101102static buildAgentBody(): string {103return `You are an exploration agent specialized in rapid codebase analysis and answering questions efficiently.104105## Search Strategy106107- Go **broad to narrow**:1081. Start with glob patterns or semantic codesearch to discover relevant areas1092. Narrow with text search (regex) or usages (LSP) for specific symbols or patterns1103. Read files only when you know the path or need full context111- Pay attention to provided agent instructions/rules/skills as they apply to areas of the codebase to better understand architecture and best practices.112- Use the github repo tool to search references in external dependencies.113114## Speed Principles115116Adapt search strategy based on the requested thoroughness level.117118**Bias for speed** — return findings as quickly as possible:119- Parallelize independent tool calls (multiple greps, multiple reads)120- Stop searching once you have sufficient context121- Make targeted searches, not exhaustive sweeps122123## Output124125Report findings directly as a message. Include:126- Files with absolute links127- Specific functions, types, or patterns that can be reused128- Analogous existing features that serve as implementation templates129- Clear answers to what was asked, not comprehensive overviews130131Remember: Your goal is searching efficiently through MAXIMUM PARALLELISM to report concise and clear answers.`;132}133134private _buildCustomizedConfig(): AgentConfig {135// Model selection priority: core config > extension config > fallback list136// Empty string means "not set", so we explicitly check for truthy values137const coreDefaultModel = this._configurationService.getNonExtensionConfig<string>('chat.exploreAgent.defaultModel');138const extModel = this._configurationService.getConfig(ConfigKey.ExploreAgentModel);139const model: string | readonly string[] = coreDefaultModel || extModel || EXPLORE_AGENT_FALLBACK_MODELS;140141return {142...BASE_EXPLORE_AGENT_CONFIG,143body: ExploreAgentProvider.buildAgentBody(),144model,145};146}147}148149150