Path: blob/main/extensions/copilot/src/extension/prompts/node/inline/inlineChatEditCodePrompt.tsx
13404 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 { PromptElement, PromptSizing, SystemMessage, UserMessage } from '@vscode/prompt-tsx';6import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService';7import { IIgnoreService } from '../../../../platform/ignore/common/ignoreService';8import { KnownSources } from '../../../../platform/languageServer/common/languageContextService';9import { IParserService } from '../../../../platform/parser/node/parserService';10import { IExperimentationService } from '../../../../platform/telemetry/common/nullExperimentationService';11import { isNotebookCellOrNotebookChatInput } from '../../../../util/common/notebooks';12import { illegalArgument } from '../../../../util/vs/base/common/errors';13import { GenericInlinePromptProps } from '../../../context/node/resolvers/genericInlineIntentInvocation';14import { SelectionSplitKind, SummarizedDocumentData, SummarizedDocumentWithSelection } from '../../../intents/node/testIntent/summarizedDocumentWithSelection';15import { EarlyStopping, LeadingMarkdownStreaming } from '../../../prompt/node/intents';16import { TextPieceClassifiers } from '../../../prompt/node/streamingEdits';17import { InstructionMessage } from '../base/instructionMessage';18import { LegacySafetyRules } from '../base/safetyRules';19import { Tag } from '../base/tag';20import { ChatToolReferences, ChatVariables, UserQuery } from '../panel/chatVariables';21import { HistoryWithInstructions } from '../panel/conversationHistory';22import { CustomInstructions } from '../panel/customInstructions';23import { ProjectLabels } from '../panel/projectLabels';24import { LanguageServerContextPrompt } from './languageServerContextPrompt';25import { SummarizedDocumentSplit } from './promptingSummarizedDocument';262728export interface InlineChatEditCodePromptProps extends GenericInlinePromptProps {29readonly ignoreCustomInstructions?: boolean;30}3132export class InlineChatEditCodePrompt extends PromptElement<InlineChatEditCodePromptProps> {3334constructor(35props: InlineChatEditCodePromptProps,36@IIgnoreService private readonly _ignoreService: IIgnoreService,37@IParserService private readonly _parserService: IParserService,38@IExperimentationService private readonly _experimentationService: IExperimentationService,39@IConfigurationService private readonly _configurationService: IConfigurationService,40) {41super(props);42}4344async render(state: void, sizing: PromptSizing) {45const context = this.props.documentContext;46const document = context.document;47const languageId = document.languageId;4849if (isNotebookCellOrNotebookChatInput(document.uri)) {50throw illegalArgument('InlineChatEditCodePrompt should not be used with a notebook!');51}5253if (languageId === 'markdown') {54throw illegalArgument('InlineChatEditCodePrompt should not be used with a markdown document!');55}5657const isIgnored = await this._ignoreService.isCopilotIgnored(document.uri);58if (isIgnored) {59return <ignoredFiles value={[document.uri]} />;60}61const { query, history, chatVariables, } = this.props.promptContext;6263const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Advanced.ProjectLabelsInline, this._experimentationService);6465const data = await SummarizedDocumentData.create(this._parserService, document, context.fileIndentInfo, context.wholeRange, SelectionSplitKind.Adjusted);6667const replyInterpreterFactory = (splitDoc: SummarizedDocumentSplit) => splitDoc.createReplyInterpreter(68LeadingMarkdownStreaming.Mute,69EarlyStopping.StopAfterFirstCodeBlock,70splitDoc.replaceSelectionStreaming,71TextPieceClassifiers.createCodeBlockClassifier(),72line => line.value.trim() !== data.placeholderText,73);7475return (76<>77<SystemMessage priority={1000}>78You are an AI programming assistant.<br />79When asked for your name, you must respond with "GitHub Copilot".<br />80You are a world class expert in programming, and especially good at {languageId}.<br />81<LegacySafetyRules />82</SystemMessage>83<HistoryWithInstructions inline={true} historyPriority={700} passPriority history={history}>84<InstructionMessage priority={1000}>85Source code is always contained in ``` blocks.<br />86The user needs help to modify some code.<br />87{data.hasCodeWithoutSelection && <>The user includes existing code and marks with {data.placeholderText} where the selected code should go.<br /></>}88</InstructionMessage>89</HistoryWithInstructions>90{useProjectLabels && <ProjectLabels priority={600} embeddedInsideUserMessage={false} />}91<UserMessage>92{!this.props.ignoreCustomInstructions && <CustomInstructions priority={725} chatVariables={chatVariables} languageId={languageId} />}93<LanguageServerContextPrompt priority={700} document={document} position={context.selection.start} requestId={this.props.promptContext.requestId} source={KnownSources.chat} />94</UserMessage>95<ChatToolReferences priority={750} promptContext={this.props.promptContext} flexGrow={1} embeddedInsideUserMessage={false} />96<ChatVariables priority={750} chatVariables={chatVariables} embeddedInsideUserMessage={false} />97<UserMessage priority={900} flexGrow={2} flexReserve={sizing.endpoint.modelMaxPromptTokens / 3}>98<SummarizedDocumentWithSelection99flexGrow={1}100tokenBudget={'usePromptSizingBudget'}101documentData={data}102createReplyInterpreter={replyInterpreterFactory}103/>104<Tag name='userPrompt'>105<UserQuery chatVariables={chatVariables} query={query} /><br />106</Tag>107{data.hasCodeWithoutSelection && <>The modified {data.placeholderText} code with ``` is:</>}108</UserMessage>109</>110);111}112}113114115