|
| 1 | +/*--------------------------------------------------------------------------------------------- |
| 2 | + * Copyright (c) Microsoft Corporation. All rights reserved. |
| 3 | + * Licensed under the MIT License. See License.txt in the project root for license information. |
| 4 | + *--------------------------------------------------------------------------------------------*/ |
| 5 | + |
| 6 | +import { PromptElement, PromptSizing, SystemMessage, UserMessage } from '@vscode/prompt-tsx'; |
| 7 | +import { ConfigKey, IConfigurationService } from '../../../../platform/configuration/common/configurationService'; |
| 8 | +import { modelNeedsStrongReplaceStringHint, modelPrefersInstructionsAfterHistory } from '../../../../platform/endpoint/common/chatModelCapabilities'; |
| 9 | +import { IExperimentationService } from '../../../../platform/telemetry/common/nullExperimentationService'; |
| 10 | +import { isLocation, isUri } from '../../../../util/common/types'; |
| 11 | +import { ToolName } from '../../../tools/common/toolNames'; |
| 12 | +import { AgentPromptProps, getEditingReminder } from '../agent/agentPrompt'; |
| 13 | +import { CopilotIdentityRules } from '../base/copilotIdentity'; |
| 14 | +import { InstructionMessage } from '../base/instructionMessage'; |
| 15 | +import { ResponseTranslationRules } from '../base/responseTranslationRules'; |
| 16 | +import { SafetyRules } from '../base/safetyRules'; |
| 17 | +import { Tag } from '../base/tag'; |
| 18 | +import { ChatToolReferences, ChatVariables, UserQuery } from './chatVariables'; |
| 19 | +import { ConversationHistoryWithTools } from './conversationHistory'; |
| 20 | +import { CustomInstructions } from './customInstructions'; |
| 21 | +import { NewFilesLocationHint } from './editCodePrompt'; |
| 22 | +import { NotebookFormat, NotebookReminderInstructions } from './notebookEditCodePrompt'; |
| 23 | +import { ProjectLabels } from './projectLabels'; |
| 24 | +import { ChatToolCalls } from './toolCalling'; |
| 25 | + |
| 26 | +export class NotebookInlinePrompt extends PromptElement<AgentPromptProps> { |
| 27 | + constructor( |
| 28 | + props: AgentPromptProps, |
| 29 | + @IConfigurationService private readonly configurationService: IConfigurationService, |
| 30 | + ) { |
| 31 | + super(props); |
| 32 | + } |
| 33 | + async render(state: void, sizing: PromptSizing) { |
| 34 | + const instructionsAfterHistory = modelPrefersInstructionsAfterHistory(this.props.endpoint.family); |
| 35 | + const hasFilesInWorkingSet = this.props.promptContext.chatVariables.find(variable => isUri(variable.value) || isLocation(variable.value)) !== undefined; |
| 36 | + const userGoalInstructions = <> |
| 37 | + {hasFilesInWorkingSet |
| 38 | + ? <>The user has a request for modifying one or more files.</> |
| 39 | + : <>If the user asks a question, then answer it.<br /> |
| 40 | + If 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.Internal.CodeSearchAgentEnabled)) ? ", or use `#codebase` in your request to automatically discover working set files." : ""}".<br /> |
| 41 | + The only exception is if you need to create new files. In that case, follow the following instructions.</>} |
| 42 | + </>; |
| 43 | + const instructions = <InstructionMessage priority={900}> |
| 44 | + <Tag name="instructions"> |
| 45 | + You are a highly sophisticated automated coding agent with expert-level knowledge across many different programming languages and frameworks.<br /> |
| 46 | + You are capable of making complex code edits across multiple files, and you can also create new files.<br /> |
| 47 | + You have a tool that you can use to edit and create files.<br /> |
| 48 | + {userGoalInstructions}<br /> |
| 49 | + For 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 /> |
| 50 | + Describe 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 /> |
| 51 | + NEVER print out a codeblock with file changes unless the user asked for it. Use the {ToolName.EditNotebook} tool instead.<br /> |
| 52 | + Do not summarize the changes after making the edits and leave the response empty if there is nothing more to add.<br /> |
| 53 | + When 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'> |
| 56 | + When using a tool, follow the json schema very carefully and make sure to include ALL required properties.<br /> |
| 57 | + Always output valid JSON when using a tool.<br /> |
| 58 | + If a tool exists to do a task, use the tool instead of asking the user to manually take an action.<br /> |
| 59 | + If you say that you will take an action, then go ahead and use the tool to do it. No need to ask permission.<br /> |
| 60 | + Never 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 /> |
| 61 | + NEVER 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>; |
| 65 | + |
| 66 | + return ( |
| 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 | +} |
| 81 | + |
| 82 | +class EditCode2UserMessage extends PromptElement<AgentPromptProps> { |
| 83 | + constructor( |
| 84 | + props: AgentPromptProps, |
| 85 | + @IExperimentationService private readonly experimentationService: IExperimentationService, |
| 86 | + @IConfigurationService private readonly _configurationService: IConfigurationService, |
| 87 | + ) { |
| 88 | + super(props); |
| 89 | + } |
| 90 | + |
| 91 | + async render(state: void, sizing: PromptSizing) { |
| 92 | + const { query, chatVariables } = this.props.promptContext; |
| 93 | + const useProjectLabels = this._configurationService.getExperimentBasedConfig(ConfigKey.Internal.ProjectLabelsChat, this.experimentationService); |
| 94 | + const hasReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.ReplaceString); |
| 95 | + const hasEditFileTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.EditFile); |
| 96 | + const hasMultiReplaceStringTool = !!this.props.promptContext.tools?.availableTools.find(tool => tool.name === ToolName.MultiReplaceString); |
| 97 | + |
| 98 | + return ( |
| 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 | +} |
0 commit comments