Path: blob/main/extensions/copilot/src/extension/prompts/node/inline/inlineChatGenerateMarkdownPrompt.tsx
13405 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, PromptElementProps, PromptReference, PromptSizing, SystemMessage, TextChunk, UserMessage } from '@vscode/prompt-tsx';6import type * as vscode from 'vscode';7import { IIgnoreService } from '../../../../platform/ignore/common/ignoreService';8import { isNotebookCellOrNotebookChatInput } from '../../../../util/common/notebooks';9import { illegalArgument } from '../../../../util/vs/base/common/errors';10import { IInstantiationService } from '../../../../util/vs/platform/instantiation/common/instantiation';11import { GenericInlinePromptProps } from '../../../context/node/resolvers/genericInlineIntentInvocation';12import { SelectionSplitKind, SummarizedDocumentData, SummarizedDocumentWithSelection } from '../../../intents/node/testIntent/summarizedDocumentWithSelection';13import { EarlyStopping, LeadingMarkdownStreaming } from '../../../prompt/node/intents';14import { TextPieceClassifiers } from '../../../prompt/node/streamingEdits';15import { InstructionMessage } from '../base/instructionMessage';16import { LegacySafetyRules } from '../base/safetyRules';17import { Tag } from '../base/tag';18import { ChatToolReferences, ChatVariables, UserQuery } from '../panel/chatVariables';19import { HistoryWithInstructions } from '../panel/conversationHistory';20import { CustomInstructions } from '../panel/customInstructions';21import { SafePromptElement } from '../panel/safeElements';22import { SummarizedDocumentSplit } from './promptingSummarizedDocument';2324export interface InlineChatGenerateMarkdownPromptProps extends GenericInlinePromptProps {25}2627export class InlineChatGenerateMarkdownPrompt extends PromptElement<InlineChatGenerateMarkdownPromptProps> {2829constructor(30props: InlineChatGenerateMarkdownPromptProps,31@IIgnoreService private readonly _ignoreService: IIgnoreService,32@IInstantiationService private readonly _instantiationService: IInstantiationService,33) {34super(props);35}3637async render(state: void, sizing: PromptSizing) {38const context = this.props.documentContext;39const document = context.document;40const languageId = document.languageId;4142if (isNotebookCellOrNotebookChatInput(this.props.documentContext.document.uri)) {43throw illegalArgument('InlineChatGenerateMarkdownPrompt should not be used with a notebook!');44}4546if (languageId !== 'markdown') {47throw illegalArgument('InlineChatGenerateMarkdownPrompt should only be used with markdown documents!');48}4950const isIgnored = await this._ignoreService.isCopilotIgnored(context.document.uri);51if (isIgnored) {52return <ignoredFiles value={[this.props.documentContext.document.uri]} />;53}5455const { query, history, chatVariables, } = this.props.promptContext;5657const data = await this._instantiationService.invokeFunction(58SummarizedDocumentData.create,59context.document,60context.fileIndentInfo,61context.wholeRange,62SelectionSplitKind.OriginalEnd63);6465const replyInterpreterFn = (splitDoc: SummarizedDocumentSplit) => splitDoc.createReplyInterpreter(66LeadingMarkdownStreaming.Mute,67EarlyStopping.None,68splitDoc.insertStreaming,69TextPieceClassifiers.createFencedBlockClassifier(MarkdownBlock.FenceSequence),70line => line.value.trim() !== data.placeholderText71);7273return (74<>75{/* <meta value={new ReplyInterpreterMetaData(replyInterpreter)} /> */}76<SystemMessage priority={1000}>77You are an AI programming assistant.<br />78When asked for your name, you must respond with "GitHub Copilot".<br />79You are a world class markdown editor, very well versed in programming.<br />80<LegacySafetyRules />81</SystemMessage>82<HistoryWithInstructions inline={true} historyPriority={700} passPriority history={history}>83<InstructionMessage priority={1000}>84The user needs help to write some new markdown.<br />85The markdown is always delimited by {MarkdownBlock.FenceSequence}.<br />86{data.hasContent && <>The user includes existing markdown and marks with {data.placeholderText} where the new code should go.<br /></>}87{data.hasContent && <>DO NOT include the text "{data.placeholderText}" in your reply.<br /></>}88{data.hasContent && <>DO NOT repeat any markdown from the user in your reply.<br /></>}89{!data.hasContent && <>Your answer must begin and end with {MarkdownBlock.FenceSequence}<br /></>}90</InstructionMessage>91</HistoryWithInstructions>92<UserMessage priority={725}>93<CustomInstructions languageId={languageId} chatVariables={chatVariables} />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={replyInterpreterFn}103/>104<Tag name='userPrompt'>105<UserQuery chatVariables={chatVariables} query={query} /><br />106</Tag>107{data.hasContent && <>Remember to start and end your answer with {MarkdownBlock.FenceSequence}. The markdown that would fit at {data.placeholderText} is:</>}108</UserMessage>109</>110);111}112}113114export type MarkdownBlockProps = PromptElementProps<{115uri: vscode.Uri | null;116code: string;117references?: PromptReference[];118}>;119120export class MarkdownBlock extends SafePromptElement<MarkdownBlockProps> {121122public static FenceSequence = `-+-+-+-+-+`;123124async render(state: void) {125const isIgnored = this.props.uri ? await this._ignoreService.isCopilotIgnored(this.props.uri) : false;126if (isIgnored) {127return this._handleFoulPrompt();128}129const fence = MarkdownBlock.FenceSequence;130const code = `${fence}\n${this.props.code}\n${fence}`;131return <TextChunk>{code}</TextChunk>;132}133}134135136