1
>
/*---------------------------------------------------------------------------------------------
runSubagentTool.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 { CancellationToken } from '../../../../../../base/common/cancellation.js';
7
>
import { Codicon } from '../../../../../../base/common/codicons.js';
8
>
import { Emitter, type Event } from '../../../../../../base/common/event.js';
9
>
import { MarkdownString } from '../../../../../../base/common/htmlContent.js';
10
>
import { IJSONSchema, IJSONSchemaMap } from '../../../../../../base/common/jsonSchema.js';
11
>
import { Disposable, DisposableStore } from '../../../../../../base/common/lifecycle.js';
12
>
import type { URI } from '../../../../../../base/common/uri.js';
13
>
import { ThemeIcon } from '../../../../../../base/common/themables.js';
14
>
import { generateUuid } from '../../../../../../base/common/uuid.js';
15
>
import { localize } from '../../../../../../nls.js';
16
>
import { IConfigurationService } from '../../../../../../platform/configuration/common/configuration.js';
17
>
import { IInstantiationService } from '../../../../../../platform/instantiation/common/instantiation.js';
18
>
import { ILogService } from '../../../../../../platform/log/common/log.js';
19
>
import { IProductService } from '../../../../../../platform/product/common/productService.js';
20
>
import { ChatRequestVariableSet } from '../../attachments/chatVariableEntries.js';
21
>
import { isByokModel } from '../../chatSelectedModel.js';
22
>
import { IChatProgress, IChatService } from '../../chatService/chatService.js';
23
>
import { ChatAgentLocation, ChatConfiguration, ChatModeKind } from '../../constants.js';
24
>
import { COPILOT_VENDOR_ID, ILanguageModelChatMetadata, ILanguageModelsService } from '../../languageModels.js';
25
>
import type { ChatModel, IChatRequestModeInstructions } from '../../model/chatModel.js';
26
>
import { getChatSessionType } from '../../model/chatUri.js';
27
>
import { IChatAgentRequest, IChatAgentResult, IChatAgentService } from '../../participants/chatAgents.js';
28
>
import { ComputeAutomaticInstructions } from '../../promptSyntax/computeAutomaticInstructions.js';
29
>
import { ChatRequestHooks, mergeHooks } from '../../promptSyntax/hookSchema.js';
30
>
import { HookType } from '../../promptSyntax/hookTypes.js';
31
>
import { ICustomAgent, IPromptsService } from '../../promptSyntax/service/promptsService.js';
32
>
import { isBuiltinAgent } from '../../promptSyntax/utils/promptsServiceUtils.js';
33
>
import {
34
>
CountTokensCallback,
35
>
ILanguageModelToolsService,
36
>
IPreparedToolInvocation,
37
>
isToolSet,
38
>
IToolData,
39
>
IToolImpl,
40
>
IToolInvocation,
41
>
IToolInvocationPreparationContext,
42
>
IToolResult,
43
>
ToolDataSource,
44
>
ToolProgress,
45
>
VSCodeToolReference,
46
>
} from '../languageModelToolsService.js';
47
>
import { ManageTodoListToolToolId } from './manageTodoListTool.js';
48
>
import { createToolSimpleTextResult } from './toolHelpers.js';
49
>
50
>
const BaseModelDescription = `Launch a new agent to handle complex, multi-step tasks autonomously. This tool is good at researching complex questions, searching for code, and executing multi-step tasks. When you are searching for a keyword or file and are not confident that you will find the right match in the first few tries, use this agent to perform the search for you.
51
>
52
>
- Agents do not run async or in the background, you will wait for the agent\'s result.
53
>
- When the agent is done, it will return a single message back to you. The result returned by the agent is not visible to the user. To show the user the result, you should send a text message back to the user with a concise summary of the result.
54
>
- Each agent invocation is stateless. You will not be able to send additional messages to the agent, nor will the agent be able to communicate with you outside of its final report. Therefore, your prompt should contain a highly detailed task description for the agent to perform autonomously and you should specify exactly what information the agent should return back to you in its final and only message to you.
55
>
- The agent's outputs should generally be trusted
56
>
- Clearly tell the agent whether you expect it to write code or just to do research (search, file reads, web fetches, etc.), since it is not aware of the user\'s intent
57
>
- If the user asks for a certain agent, you MUST provide that EXACT agent name (case-sensitive) to invoke that specific agent.`;
58
>
59
>
export interface IRunSubagentToolInputParams {
60
>
prompt: string;
61
>
description: string;
62
>
agentName?: string;
63
>
model?: string;
64
>
}
65
>
66
>
export const RUN_SUBAGENT_MAX_NESTING_DEPTH = 5;
67
>
68
>
export class RunSubagentTool extends Disposable implements IToolImpl {
69
>
70
>
static readonly Id = 'runSubagent';
71
>
72
>
private readonly _onDidUpdateToolData = this._register(new Emitter<void>());
73
>
readonly onDidUpdateToolData: Event<void> = this._onDidUpdateToolData.event;
74
>
75
>
/** Hack to port data between prepare/invoke */
76
>
private readonly _resolvedModels = new Map<string, { modeModelId: string | undefined; resolvedModelName: string | undefined }>();
77
>
78
>
/** Tracks the current subagent nesting depth per session to detect and limit recursion. */
79
>
private readonly _sessionDepth = new Map<string, number>();
80
>
81
>
constructor(
82
@IChatAgentService private readonly chatAgentService: IChatAgentService,
83
@IChatService private readonly chatService: IChatService,