mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-18 06:09:20 +01:00
548eda26df
* feat: define workspace metadata OTel attributes and resolver Add CopilotChatAttr constants for repo.head_branch_name, repo.head_commit_hash, repo.remote_url, and file.relative_path. Create WorkspaceOTelMetadata interface and resolveWorkspaceOTelMetadata() helper that synchronously resolves git metadata from activeRepository. Refs: microsoft/vscode#306397, microsoft/vscode-internalbacklog#7297 * feat: extend OTel edit events with optional workspace metadata Add optional WorkspaceOTelMetadata param to emitEditFeedbackEvent, emitEditHunkActionEvent, emitInlineDoneEvent, emitEditSurvivalEvent. Existing callers compile unchanged since the new param is optional. Refs: microsoft/vscode#306397 * feat: add workspace metadata to invoke_agent OTel span Inject IGitService into ToolCallingLoop and spread resolved workspace metadata (branch, commit, remote) onto the invoke_agent span attributes. Refs: microsoft/vscode#306397 * feat: extend EditSurvivalResult with workspace metadata Add workspace field to EditSurvivalResult interface and populate it in EditSurvivalReporter._report() using resolveWorkspaceOTelMetadata(). The reporter already injects IGitService and has the document URI, so no new DI is needed. Refs: microsoft/vscode#306397 * feat: inject IGitService into UserActions and pass workspace metadata Add workspace metadata to emitEditFeedbackEvent, emitEditHunkActionEvent, and emitInlineDoneEvent calls in UserFeedbackService using the file URI from each event action. Refs: microsoft/vscode#306397 * feat: pass workspace metadata to OTel survival events Forward res.workspace from EditSurvivalResult to emitEditSurvivalEvent at all 4 call sites: inline_chat, code_mapper, apply_patch, replace_string. Refs: microsoft/vscode#306397 * feat: add workspace metadata to GH telemetry edit events Add headBranchName, headCommitHash, remoteUrl, fileRelativePath to sendGHTelemetryEvent/sendEnhancedGHTelemetryEvent calls for: - inline.trackEditSurvival - fastApply/trackEditSurvival - applyPatch/trackEditSurvival - replaceString/trackEditSurvival - fastApply/editOutcome Refs: microsoft/vscode-internalbacklog#7297 * test: add unit tests for workspace metadata resolver and events Test resolveWorkspaceOTelMetadata (branch, commit, URL, relative path, edge cases) and workspaceMetadataToOTelAttributes (OTel key mapping). Add tests for emitEditFeedbackEvent and emitEditSurvivalEvent verifying workspace metadata is included/omitted correctly. Refs: microsoft/vscode#306397 * fix: propagate IGitService to ToolCallingLoop subclasses Pass the new IGitService constructor parameter through to super() in all 5 ToolCallingLoop subclasses: McpToolCallingLoop, CodebaseToolCallingLoop, DefaultToolCallingLoop, ExecutionSubagentToolCallingLoop, SearchSubagentToolCallingLoop. Refs: microsoft/vscode#306397 * fix: address review - URI-safe path, brace style, trim tests - Fix path prefix false-positive by using isEqualOrParent/relativePath instead of string startsWith (e.g. /repo matching /repo2/file.ts) - Expand one-line if blocks to multi-line per repo coding standards - Remove as-any mutation in test, remove trivial conversion tests, add test for path prefix false-positive edge case
107 lines
5.3 KiB
TypeScript
107 lines
5.3 KiB
TypeScript
/*---------------------------------------------------------------------------------------------
|
|
* Copyright (c) Microsoft Corporation. All rights reserved.
|
|
* Licensed under the MIT License. See License.txt in the project root for license information.
|
|
*--------------------------------------------------------------------------------------------*/
|
|
|
|
import { randomUUID } from 'crypto';
|
|
import type { CancellationToken, ChatRequest, LanguageModelToolInformation, Progress } from 'vscode';
|
|
import { IAuthenticationChatUpgradeService } from '../../../platform/authentication/common/authenticationUpgrade';
|
|
import { IChatHookService } from '../../../platform/chat/common/chatHookService';
|
|
import { ChatLocation, ChatResponse } from '../../../platform/chat/common/commonTypes';
|
|
import { ISessionTranscriptService } from '../../../platform/chat/common/sessionTranscriptService';
|
|
import { IConfigurationService } from '../../../platform/configuration/common/configurationService';
|
|
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
|
|
import { IFileSystemService } from '../../../platform/filesystem/common/fileSystemService';
|
|
import { IGitService } from '../../../platform/git/common/gitService';
|
|
import { ILogService } from '../../../platform/log/common/logService';
|
|
import { IOTelService } from '../../../platform/otel/common/otelService';
|
|
import { IRequestLogger } from '../../../platform/requestLogger/node/requestLogger';
|
|
import { IExperimentationService } from '../../../platform/telemetry/common/nullExperimentationService';
|
|
import { ITelemetryService } from '../../../platform/telemetry/common/telemetry';
|
|
import { IInstantiationService } from '../../../util/vs/platform/instantiation/common/instantiation';
|
|
import { ChatResponseProgressPart, ChatResponseReferencePart } from '../../../vscodeTypes';
|
|
import { IToolCallingLoopOptions, ToolCallingLoop, ToolCallingLoopFetchOptions } from '../../intents/node/toolCallingLoop';
|
|
import { PromptRenderer } from '../../prompts/node/base/promptRenderer';
|
|
import { CodebaseAgentPrompt } from '../../prompts/node/panel/codebaseAgentPrompt';
|
|
import { IToolsService } from '../../tools/common/toolsService';
|
|
import { IBuildPromptContext } from '../common/intents';
|
|
import { IBuildPromptResult } from './intents';
|
|
|
|
export interface ICodebaseToolCallingLoopOptions extends IToolCallingLoopOptions {
|
|
request: ChatRequest;
|
|
location: ChatLocation;
|
|
}
|
|
|
|
export class CodebaseToolCallingLoop extends ToolCallingLoop<ICodebaseToolCallingLoopOptions> {
|
|
|
|
public static readonly ID = 'codebaseTool';
|
|
|
|
constructor(
|
|
options: ICodebaseToolCallingLoopOptions,
|
|
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
|
@ILogService logService: ILogService,
|
|
@IRequestLogger requestLogger: IRequestLogger,
|
|
@IEndpointProvider private readonly endpointProvider: IEndpointProvider,
|
|
@IToolsService private readonly toolsService: IToolsService,
|
|
@IAuthenticationChatUpgradeService authenticationChatUpgradeService: IAuthenticationChatUpgradeService,
|
|
@ITelemetryService telemetryService: ITelemetryService,
|
|
@IConfigurationService configurationService: IConfigurationService,
|
|
@IExperimentationService experimentationService: IExperimentationService,
|
|
@IChatHookService chatHookService: IChatHookService,
|
|
@ISessionTranscriptService sessionTranscriptService: ISessionTranscriptService,
|
|
@IFileSystemService fileSystemService: IFileSystemService,
|
|
@IOTelService otelService: IOTelService,
|
|
@IGitService gitService: IGitService,
|
|
) {
|
|
super(options, instantiationService, endpointProvider, logService, requestLogger, authenticationChatUpgradeService, telemetryService, configurationService, experimentationService, chatHookService, sessionTranscriptService, fileSystemService, otelService, gitService);
|
|
}
|
|
|
|
private async getEndpoint(request: ChatRequest) {
|
|
let endpoint = await this.endpointProvider.getChatEndpoint(this.options.request);
|
|
if (!endpoint.supportsToolCalls) {
|
|
endpoint = await this.endpointProvider.getChatEndpoint('copilot-base');
|
|
}
|
|
return endpoint;
|
|
}
|
|
|
|
protected async buildPrompt(buildPromptContext: IBuildPromptContext, progress: Progress<ChatResponseReferencePart | ChatResponseProgressPart>, token: CancellationToken): Promise<IBuildPromptResult> {
|
|
const endpoint = await this.getEndpoint(this.options.request);
|
|
const renderer = PromptRenderer.create(
|
|
this.instantiationService,
|
|
endpoint,
|
|
CodebaseAgentPrompt,
|
|
{
|
|
promptContext: buildPromptContext
|
|
}
|
|
);
|
|
return await renderer.render(progress, token);
|
|
}
|
|
|
|
protected async getAvailableTools(): Promise<LanguageModelToolInformation[]> {
|
|
const endpoint = await this.getEndpoint(this.options.request);
|
|
return this.toolsService.getEnabledTools(this.options.request, endpoint, tool => tool.tags.includes('vscode_codesearch'));
|
|
}
|
|
|
|
protected async fetch({ messages, finishedCb, requestOptions }: ToolCallingLoopFetchOptions, token: CancellationToken): Promise<ChatResponse> {
|
|
const endpoint = await this.getEndpoint(this.options.request);
|
|
return endpoint.makeChatRequest(
|
|
CodebaseToolCallingLoop.ID,
|
|
messages,
|
|
finishedCb,
|
|
token,
|
|
this.options.location,
|
|
undefined,
|
|
{
|
|
...requestOptions,
|
|
temperature: 0
|
|
},
|
|
// This loop is inside a tool called from another request, so never user initiated
|
|
false,
|
|
{
|
|
messageId: randomUUID(), // @TODO@joyceerhl
|
|
messageSource: CodebaseToolCallingLoop.ID
|
|
},
|
|
);
|
|
}
|
|
}
|