From 26f1db756d8ddbb24f84eb1df26890eb0d2ee2bd Mon Sep 17 00:00:00 2001 From: Kevin Kent Date: Thu, 30 Apr 2026 13:51:26 -0700 Subject: [PATCH] Replace requestKind literal strings with RequestKind constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Collapse the four IBackgroundRequestOptions / ISubagentRequestOptions / ISummarizationRequestOptions / IMainAgentRequestOptions interfaces into a single 'as const' object + derived type, matching the existing ToolName / ContributedToolName pattern in this codebase. Call sites now use RequestKind.MainAgent etc. instead of hand-typing 'mainagent', so a future rename only has to update the RequestKind definition. Compile-time safety is unchanged — IRequestKindOptions.kind is still typed as the union of literals. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- .../inlineChat/node/inlineChatIntent.ts | 6 +-- .../src/extension/intents/node/agentIntent.ts | 4 +- .../extension/prompt/node/chatMLFetcher.ts | 8 +-- .../prompt/node/chatMLFetcherTelemetry.ts | 8 +-- .../node/defaultIntentRequestHandler.ts | 5 +- .../node/executionSubagentToolCallingLoop.ts | 3 +- .../node/searchSubagentToolCallingLoop.ts | 3 +- .../src/extension/prompt/node/summarizer.ts | 3 +- .../agent/summarizedConversationHistory.tsx | 4 +- .../platform/networking/common/networking.ts | 53 ++++++++----------- 10 files changed, 46 insertions(+), 51 deletions(-) diff --git a/extensions/copilot/src/extension/inlineChat/node/inlineChatIntent.ts b/extensions/copilot/src/extension/inlineChat/node/inlineChatIntent.ts index f52e6094e73..b0abb53f31f 100644 --- a/extensions/copilot/src/extension/inlineChat/node/inlineChatIntent.ts +++ b/extensions/copilot/src/extension/inlineChat/node/inlineChatIntent.ts @@ -17,7 +17,7 @@ import { IOctoKitService } from '../../../platform/github/common/githubService'; import { IIgnoreService } from '../../../platform/ignore/common/ignoreService'; import { ILogService } from '../../../platform/log/common/logService'; import { Prediction } from '../../../platform/networking/common/fetch'; -import { IChatEndpoint, IMakeChatRequestOptions } from '../../../platform/networking/common/networking'; +import { IChatEndpoint, IMakeChatRequestOptions, RequestKind } from '../../../platform/networking/common/networking'; import { IParserService } from '../../../platform/parser/node/parserService'; import { getWasmLanguage } from '../../../platform/parser/node/treeSitterLanguages'; import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService'; @@ -468,7 +468,7 @@ class InlineChatEditToolsStrategy implements IInlineChatEditStrategy { conversationId: telemetry.sessionId, messageSource: this._intent.id }, - requestKindOptions: { kind: 'mainagent' }, + requestKindOptions: { kind: RequestKind.MainAgent }, finishedCb: async (_text, _index, delta) => { telemetry.markReceivedToken(); @@ -668,7 +668,7 @@ class InlineChatEditHeuristicStrategy implements IInlineChatEditStrategy { conversationId: telemetry.sessionId, messageSource: this._intent.id }, - requestKindOptions: { kind: 'mainagent' }, + requestKindOptions: { kind: RequestKind.MainAgent }, requestOptions: { stream: true, prediction diff --git a/extensions/copilot/src/extension/intents/node/agentIntent.ts b/extensions/copilot/src/extension/intents/node/agentIntent.ts index 1db2a4dfe69..d5aec913b5b 100644 --- a/extensions/copilot/src/extension/intents/node/agentIntent.ts +++ b/extensions/copilot/src/extension/intents/node/agentIntent.ts @@ -19,7 +19,7 @@ import { IEnvService } from '../../../platform/env/common/envService'; import { ILogService } from '../../../platform/log/common/logService'; import { IEditLogService } from '../../../platform/multiFileEdit/common/editLogService'; import { CUSTOM_TOOL_SEARCH_NAME, isAnthropicContextEditingEnabled } from '../../../platform/networking/common/anthropic'; -import { IChatEndpoint } from '../../../platform/networking/common/networking'; +import { IChatEndpoint, RequestKind } from '../../../platform/networking/common/networking'; import { modelsWithoutResponsesContextManagement } from '../../../platform/networking/common/openai'; import { INotebookService } from '../../../platform/notebook/common/notebookService'; import { GenAiMetrics } from '../../../platform/otel/common/genAiMetrics'; @@ -864,7 +864,7 @@ export class AgentIntentInvocation extends EditCodeIntentInvocation implements I modelCapabilities, telemetryProperties: associatedRequestId ? { associatedRequestId } : undefined, enableRetryOnFilter: true, - requestKindOptions: { kind: 'summarization' }, + requestKindOptions: { kind: RequestKind.Summarization }, }, bgToken); if (response.type !== ChatFetchResponseType.Success) { throw new Error(`Background inline summarization request failed: ${response.type}`); diff --git a/extensions/copilot/src/extension/prompt/node/chatMLFetcher.ts b/extensions/copilot/src/extension/prompt/node/chatMLFetcher.ts index 1bb90a20019..deb290663e6 100644 --- a/extensions/copilot/src/extension/prompt/node/chatMLFetcher.ts +++ b/extensions/copilot/src/extension/prompt/node/chatMLFetcher.ts @@ -21,7 +21,7 @@ import { getResponsesApiCompactionThresholdFromBody, OpenAIResponsesProcessor, r import { collectSingleLineErrorMessage, ILogService } from '../../../platform/log/common/logService'; import { FinishedCallback, getRequestId, IResponseDelta, OptionalChatRequestParams, RequestId } from '../../../platform/networking/common/fetch'; import { FetcherId, IFetcherService, Response } from '../../../platform/networking/common/fetcherService'; -import { IChatEndpoint, IEndpointBody, IRequestKindOptions, postRequest, stringifyUrlOrRequestMetadata } from '../../../platform/networking/common/networking'; +import { IChatEndpoint, IEndpointBody, IRequestKindOptions, postRequest, RequestKind, stringifyUrlOrRequestMetadata } from '../../../platform/networking/common/networking'; import { CAPIChatMessage, ChatCompletion, FilterReason, FinishedCompletionReason, rawMessageToCAPI } from '../../../platform/networking/common/openai'; import { sendEngineMessagesTelemetry } from '../../../platform/networking/node/chatStream'; import { CAPIWebSocketErrorEvent, IChatWebSocketManager, isCAPIWebSocketError } from '../../../platform/networking/node/chatWebSocketManager'; @@ -142,7 +142,7 @@ export class ChatMLFetcherImpl extends AbstractChatMLFetcher { // explicitly opt in to 'mainagent'. This way new utility callers get classified // correctly without each one having to remember to opt in. if (!requestKindOptions) { - requestKindOptions = { kind: 'background' }; + requestKindOptions = { kind: RequestKind.Background }; } if (useWebSocket && this._consecutiveWebSocketRetryFallbacks >= ChatMLFetcherImpl._maxConsecutiveWebSocketFallbacks) { this._logService.debug(`[ChatWebSocketManager] Disabling WebSocket for request due to ${this._consecutiveWebSocketRetryFallbacks} consecutive WebSocket failures with successful HTTP fallback.`); @@ -1076,9 +1076,9 @@ export class ChatMLFetcherImpl extends AbstractChatMLFetcher { summarizedAtRoundId: string | undefined, ): Promise<{ result: ChatResults | ChatRequestFailed | ChatRequestCanceled }> { const intent = locationToIntent(location); - const agentInteractionType = requestKindOptions?.kind === 'subagent' ? + const agentInteractionType = requestKindOptions?.kind === RequestKind.Subagent ? 'conversation-subagent' : - requestKindOptions?.kind === 'background' ? + requestKindOptions?.kind === RequestKind.Background ? 'conversation-background' : intent === 'conversation-agent' ? intent : undefined; const additionalHeaders: Record = { diff --git a/extensions/copilot/src/extension/prompt/node/chatMLFetcherTelemetry.ts b/extensions/copilot/src/extension/prompt/node/chatMLFetcherTelemetry.ts index 6038f9072c0..db92b964f51 100644 --- a/extensions/copilot/src/extension/prompt/node/chatMLFetcherTelemetry.ts +++ b/extensions/copilot/src/extension/prompt/node/chatMLFetcherTelemetry.ts @@ -6,7 +6,7 @@ import { ChatFetchError } from '../../../platform/chat/common/commonTypes'; import { isAutoModel } from '../../../platform/endpoint/node/autoChatEndpoint'; import { FetcherId } from '../../../platform/networking/common/fetcherService'; -import { IChatEndpoint, IChatRequestTelemetryProperties, IEndpointBody, IRequestKindOptions } from '../../../platform/networking/common/networking'; +import { IChatEndpoint, IChatRequestTelemetryProperties, IEndpointBody, IRequestKindOptions, RequestKind } from '../../../platform/networking/common/networking'; import { ChatCompletion } from '../../../platform/networking/common/openai'; import { ITelemetryService } from '../../../platform/telemetry/common/telemetry'; import { TelemetryData } from '../../../platform/telemetry/common/telemetryData'; @@ -160,7 +160,7 @@ export class ChatMLFetcherTelemetrySender { filterReason: chatCompletion.filterReason, source: baseTelemetry?.properties.messageSource ?? 'unknown', initiatorType: userInitiatedRequest ? 'user' : 'agent', - requestKind: requestKindOptions?.kind ?? 'mainagent', + requestKind: requestKindOptions?.kind ?? RequestKind.MainAgent, conversationId: baseTelemetry?.properties.conversationId, model: chatEndpointInfo?.model, modelInvoked: chatCompletion.model, @@ -277,7 +277,7 @@ export class ChatMLFetcherTelemetrySender { source, requestId, model, - requestKind: requestKindOptions?.kind ?? 'mainagent', + requestKind: requestKindOptions?.kind ?? RequestKind.MainAgent, conversationId, associatedRequestId, parentRequestId, @@ -371,7 +371,7 @@ export class ChatMLFetcherTelemetrySender { type: processed.type, reason: processed.reasonDetail || processed.reason, source: telemetryProperties?.messageSource ?? 'unknown', - requestKind: requestKindOptions?.kind ?? 'mainagent', + requestKind: requestKindOptions?.kind ?? RequestKind.MainAgent, conversationId: telemetryProperties?.conversationId, requestId: processed.requestId, gitHubRequestId: processed.serverRequestId, diff --git a/extensions/copilot/src/extension/prompt/node/defaultIntentRequestHandler.ts b/extensions/copilot/src/extension/prompt/node/defaultIntentRequestHandler.ts index 68ae6c2be42..093464cb780 100644 --- a/extensions/copilot/src/extension/prompt/node/defaultIntentRequestHandler.ts +++ b/extensions/copilot/src/extension/prompt/node/defaultIntentRequestHandler.ts @@ -23,6 +23,7 @@ import { HAS_IGNORED_FILES_MESSAGE } from '../../../platform/ignore/common/ignor import { ILogService } from '../../../platform/log/common/logService'; import { isAnthropicContextEditingEnabled } from '../../../platform/networking/common/anthropic'; import { FilterReason } from '../../../platform/networking/common/openai'; +import { RequestKind } from '../../../platform/networking/common/networking'; import { IOTelService } from '../../../platform/otel/common/otelService'; import { CapturingToken } from '../../../platform/requestLogger/common/capturingToken'; import { IRequestLogger } from '../../../platform/requestLogger/common/requestLogger'; @@ -731,8 +732,8 @@ class DefaultToolCallingLoop extends ToolCallingLoop { parentRequestId: this.options.request.parentRequestId, }, requestKindOptions: this.options.request.subAgentInvocationId - ? { kind: 'subagent' } - : { kind: 'mainagent' }, + ? { kind: RequestKind.Subagent } + : { kind: RequestKind.MainAgent }, enableRetryOnFilter: true }, token); } diff --git a/extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts b/extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts index aa01f5cffae..4162c19dd8f 100644 --- a/extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts +++ b/extensions/copilot/src/extension/prompt/node/executionSubagentToolCallingLoop.ts @@ -13,6 +13,7 @@ import { ConfigKey, IConfigurationService } from '../../../platform/configuratio import { ChatEndpointFamily, IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider'; import { ProxyAgenticEndpoint } from '../../../platform/endpoint/node/proxyAgenticEndpoint'; import { IFileSystemService } from '../../../platform/filesystem/common/fileSystemService'; +import { RequestKind } from '../../../platform/networking/common/networking'; import { IGitService } from '../../../platform/git/common/gitService'; import { ILogService } from '../../../platform/log/common/logService'; import { IOTelService } from '../../../platform/otel/common/otelService'; @@ -154,7 +155,7 @@ export class ExecutionSubagentToolCallingLoop extends ToolCallingLoop`. Anything that doesn't + * set `requestKindOptions` is classified as `RequestKind.Background` by `chatMLFetcher`. */ -export interface IBackgroundRequestOptions { - readonly kind: 'background'; -} +export const RequestKind = { + Background: 'background', + Subagent: 'subagent', + Summarization: 'summarization', + MainAgent: 'mainagent', +} as const; +export type RequestKind = typeof RequestKind[keyof typeof RequestKind]; -/** - * A subagent request is a request made by a subagent, indicated with a subAgentInvocationId included in the request from VS Code. - */ -export interface ISubagentRequestOptions { - readonly kind: 'subagent'; +export interface IRequestKindOptions { + readonly kind: RequestKind; } -/** - * A summarization request — used for compacting conversation history (both - * inline mid-turn and post-turn). Distinct from 'background' because it's - * directly in the critical path of a user turn. - */ -export interface ISummarizationRequestOptions { - readonly kind: 'summarization'; -} - -/** - * A normal request is a primary user-initiated chat turn (e.g. driven by the - * default intent request handler or inline chat). Callers explicitly opt in to - * 'mainagent' so the chat ML fetcher can default unmarked requests to 'background'. - */ -export interface IMainAgentRequestOptions { - readonly kind: 'mainagent'; -} - -export type IRequestKindOptions = IBackgroundRequestOptions | ISubagentRequestOptions | ISummarizationRequestOptions | IMainAgentRequestOptions; - function networkRequest( accessor: ServicesAccessor, options: INetworkRequestOptions, @@ -409,9 +400,9 @@ function networkRequest( name: '', version: '', } satisfies IEndpoint : endpointOrUrl; - const agentInteractionType = options.requestKindOptions?.kind === 'subagent' ? + const agentInteractionType = options.requestKindOptions?.kind === RequestKind.Subagent ? 'conversation-subagent' : - options.requestKindOptions?.kind === 'background' ? + options.requestKindOptions?.kind === RequestKind.Background ? 'conversation-background' : intent === 'conversation-agent' ? intent : intent;