Path: blob/main/extensions/copilot/src/extension/prompts/node/panel/notebookInlinePrompt.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, PromptSizing, SystemMessage, UserMessage } from '@vscode/prompt-tsx';6import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService';7import { modelNeedsStrongReplaceStringHint, modelPrefersInstructionsAfterHistory } from '../../../../platform/endpoint/common/chatModelCapabilities';8import { IExperimentationService } from '../../../../platform/telemetry/common/nullExperimentationService';9import { isLocation, isUri } from '../../../../util/common/types';10import { ToolName } from '../../../tools/common/toolNames';11import { AgentPromptProps } from '../agent/agentPrompt';12import { getEditingReminder } from '../agent/defaultAgentInstructions';13import { CopilotIdentityRules } from '../base/copilotIdentity';14import { InstructionMessage } from '../base/instructionMessage';15import { ResponseTranslationRules } from '../base/responseTranslationRules';16import { SafetyRules } from '../base/safetyRules';17import { Tag } from '../base/tag';18import { ChatToolReferences, ChatVariables, UserQuery } from './chatVariables';19import { ConversationHistoryWithTools } from './conversationHistory';20import { CustomInstructions } from './customInstructions';21import { NewFilesLocationHint } from './editCodePrompt';22import { NotebookFormat, NotebookReminderInstructions } from './notebookEditCodePrompt';23import { ProjectLabels } from './projectLabels';24import { ChatToolCalls } from './toolCalling';2526export class NotebookInlinePrompt extends PromptElement<AgentPromptProps> {27constructor(28props: AgentPromptProps,29@IConfigurationService private readonly configurationService: IConfigurationService,30) {31super(props);32}33async render(state: void, sizing: PromptSizing) {34const instructionsAfterHistory = modelPrefersInstructionsAfterHistory(this.props.endpoint.family);35const hasFilesInWorkingSet = this.props.promptContext.chatVariables.find(variable => isUri(variable.value) || isLocation(variable.value)) !== undefined;36const userGoalInstructions = <>37{hasFilesInWorkingSet38? <>The user has a request for modifying one or more files.</>39: <>If the user asks a question, then answer it.<br />40If you need to change existing files and it's not clear which files should be changed, then refuse and answer with "Please add the files to be modified to the working set{(this.configurationService.getConfig(ConfigKey.CodeSearchAgentEnabled) || this.configurationService.getConfig(ConfigKey.Advanced.CodeSearchAgentEnabled)) ? ', or use `#codebase` in your request to automatically discover working set files.' : ''}".<br />41The only exception is if you need to create new files. In that case, follow the following instructions.</>}42</>;43const instructions = <InstructionMessage priority={900}>44<Tag name='instructions'>45You are a highly sophisticated automated coding agent with expert-level knowledge across many different programming languages and frameworks.<br />46You are capable of making complex code edits across multiple files, and you can also create new files.<br />47You have a tool that you can use to edit and create files.<br />48{userGoalInstructions}<br />49For each file, first give a very short summary of what needs to be changed, then use the tool to edit the file. If you want to edit multiple files, you can use the tool multiple times in a response to edit multiple files simultaneously. This is faster than editing files one by one.<br />50Describe the changes you'll make BEFORE editing the files. But never write out a codeblock with the changes, only pass them to the tool.<br />51NEVER print out a codeblock with file changes unless the user asked for it. Use the {ToolName.EditNotebook} tool instead.<br />52Do not summarize the changes after making the edits and leave the response empty if there is nothing more to add.<br />53When describing your changes to the user, keep your descriptions very concise and to the point, and do not repeat anything that you previously described.54</Tag>55<Tag name='toolUseInstructions'>56When using a tool, follow the json schema very carefully and make sure to include ALL required properties.<br />57Always output valid JSON when using a tool.<br />58If a tool exists to do a task, use the tool instead of asking the user to manually take an action.<br />59If you say that you will take an action, then go ahead and use the tool to do it. No need to ask permission.<br />60Never use multi_tool_use.parallel or any tool that does not exist. Use tools using the proper procedure, DO NOT write out a json codeblock with the tool inputs.<br />61NEVER say the name of a tool to a user. For example, instead of saying that you'll use the {ToolName.EditNotebook} tool, say "I'll edit the project.js file".<br />62</Tag>63<ResponseTranslationRules />64</InstructionMessage>;6566return (67<>68<SystemMessage priority={1000}>69<CopilotIdentityRules />70<SafetyRules />71</SystemMessage>72{instructionsAfterHistory ? undefined : instructions}73<ConversationHistoryWithTools flexGrow={1} priority={700} promptContext={this.props.promptContext} />74{instructionsAfterHistory ? instructions : undefined}75<EditCode2UserMessage flexGrow={2} priority={900} promptContext={this.props.promptContext} endpoint={this.props.endpoint} location={this.props.location} />76<ChatToolCalls priority={899} flexGrow={3} promptContext={this.props.promptContext} toolCallRounds={this.props.promptContext.toolCallRounds} toolCallResults={this.props.promptContext.toolCallResults} />77</>78);79}80}8182class EditCode2UserMessage extends PromptElement<AgentPromptProps> {83constructor(84props: AgentPromptProps,85@IExperimentationService private readonly experimentationService: IExperimentationService,86@IConfigurationService private readonly _configurationService: IConfigurationService,87) {88super(props);89}9091async render(state: void, sizing: PromptSizing) {92const { query, chatVariables } = this.props.promptContext;93const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Advanced.ProjectLabelsChat, this.experimentationService);94const hasReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.ReplaceString);95const hasEditFileTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.EditFile);96const hasMultiReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.MultiReplaceString);9798return (99<>100<UserMessage>101{useProjectLabels && <ProjectLabels flexGrow={1} priority={600} />}102<CustomInstructions flexGrow={6} priority={750} languageId={undefined} chatVariables={chatVariables} />103<NotebookFormat flexGrow={5} priority={810} chatVariables={chatVariables} query={query} />104<ChatToolReferences flexGrow={4} priority={898} promptContext={this.props.promptContext} documentContext={this.props.documentContext} />105<ChatVariables flexGrow={3} priority={898} chatVariables={chatVariables} />106<Tag name='reminder'>107{getEditingReminder(hasEditFileTool, hasReplaceStringTool, modelNeedsStrongReplaceStringHint(this.props.endpoint), hasMultiReplaceStringTool)}108<NotebookReminderInstructions chatVariables={chatVariables} query={query} />109<NewFilesLocationHint />110</Tag>111<Tag name='prompt'><UserQuery flexGrow={7} priority={900} chatVariables={chatVariables} query={query} /></Tag>112</UserMessage>113</>114);115}116}117118119