Skip to content

Commit 7c6c373

Browse files
authored
more specialized prompt for notebook inline (#1685)
1 parent 4b36c53 commit 7c6c373

File tree

4 files changed

+124
-18
lines changed

4 files changed

+124
-18
lines changed

src/extension/intents/node/agentIntent.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ import { applyPatch5Description } from '../../tools/node/applyPatchTool';
5151
import { addCacheBreakpoints } from './cacheBreakpoints';
5252
import { EditCodeIntent, EditCodeIntentInvocation, EditCodeIntentInvocationOptions, mergeMetadata, toNewChatReferences } from './editCodeIntent';
5353
import { getRequestedToolCallIterationLimit, IContinueOnErrorConfirmation } from './toolCallingLoop';
54+
import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt';
5455

5556
export const getAgentTools = (instaService: IInstantiationService, request: vscode.ChatRequest) =>
5657
instaService.invokeFunction(async accessor => {
@@ -197,7 +198,7 @@ export class AgentIntentInvocation extends EditCodeIntentInvocation implements I
197198

198199
public override readonly codeblocksRepresentEdits = false;
199200

200-
protected prompt: typeof AgentPrompt | typeof EditCodePrompt2 = AgentPrompt;
201+
protected prompt: typeof AgentPrompt | typeof EditCodePrompt2 | typeof NotebookInlinePrompt = AgentPrompt;
201202

202203
protected extraPromptProps: Partial<AgentPromptProps> | undefined;
203204

src/extension/intents/node/editCodeIntent2.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import { IToolsService } from '../../tools/common/toolsService';
3030
import { AgentIntentInvocation } from './agentIntent';
3131
import { EditCodeIntent, EditCodeIntentOptions } from './editCodeIntent';
3232
import { getRequestedToolCallIterationLimit } from './toolCallingLoop';
33+
import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt';
3334

3435

3536
const getTools = (instaService: IInstantiationService, request: vscode.ChatRequest): Promise<vscode.LanguageModelToolInformation[]> =>
@@ -92,7 +93,7 @@ export class EditCode2IntentInvocation extends AgentIntentInvocation {
9293
return { disable: false };
9394
}
9495

95-
protected override prompt = EditCodePrompt2;
96+
protected override prompt: typeof EditCodePrompt2 | typeof NotebookInlinePrompt = EditCodePrompt2;
9697

9798
constructor(
9899
intent: IIntent,

src/extension/intents/node/notebookEditorIntent.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,13 @@
66
import type * as vscode from 'vscode';
77
import { ChatLocation } from '../../../platform/chat/common/commonTypes';
88
import { ConfigKey, IConfigurationService } from '../../../platform/configuration/common/configurationService';
9-
import { modelSupportsMultiReplaceString, modelSupportsReplaceString } from '../../../platform/endpoint/common/chatModelCapabilities';
109
import { IEndpointProvider } from '../../../platform/endpoint/common/endpointProvider';
1110
import { IEnvService } from '../../../platform/env/common/envService';
1211
import { ILogService } from '../../../platform/log/common/logService';
1312
import { IEditLogService } from '../../../platform/multiFileEdit/common/editLogService';
1413
import { IChatEndpoint } from '../../../platform/networking/common/networking';
1514
import { IAlternativeNotebookContentService } from '../../../platform/notebook/common/alternativeContent';
16-
import { getCellId, requestHasNotebookRefs } from '../../../platform/notebook/common/helpers';
15+
import { getCellId } from '../../../platform/notebook/common/helpers';
1716
import { INotebookService } from '../../../platform/notebook/common/notebookService';
1817
import { IPromptPathRepresentationService } from '../../../platform/prompts/common/promptPathRepresentationService';
1918
import { ITabsAndEditorsService } from '../../../platform/tabs/common/tabsAndEditorsService';
@@ -29,6 +28,7 @@ import { IBuildPromptContext, InternalToolReference } from '../../prompt/common/
2928
import { IDefaultIntentRequestHandlerOptions } from '../../prompt/node/defaultIntentRequestHandler';
3029
import { IBuildPromptResult, IIntent } from '../../prompt/node/intents';
3130
import { ICodeMapperService } from '../../prompts/node/codeMapper/codeMapperService';
31+
import { NotebookInlinePrompt } from '../../prompts/node/panel/notebookInlinePrompt';
3232
import { getToolName, ToolName } from '../../tools/common/toolNames';
3333
import { IToolsService } from '../../tools/common/toolsService';
3434
import { EditCodeIntent, EditCodeIntentOptions } from './editCodeIntent';
@@ -38,22 +38,8 @@ import { getRequestedToolCallIterationLimit } from './toolCallingLoop';
3838
const getTools = (instaService: IInstantiationService, request: vscode.ChatRequest): Promise<vscode.LanguageModelToolInformation[]> =>
3939
instaService.invokeFunction(async accessor => {
4040
const toolsService = accessor.get<IToolsService>(IToolsService);
41-
const endpointProvider = accessor.get<IEndpointProvider>(IEndpointProvider);
42-
const notebookService = accessor.get<INotebookService>(INotebookService);
43-
const model = await endpointProvider.getChatEndpoint(request);
4441
const lookForTools = new Set<string>([ToolName.EditFile]);
4542

46-
if (requestHasNotebookRefs(request, notebookService, { checkPromptAsWell: true })) {
47-
lookForTools.add(ToolName.CreateNewJupyterNotebook);
48-
}
49-
50-
if (await modelSupportsReplaceString(model)) {
51-
lookForTools.add(ToolName.ReplaceString);
52-
if (await modelSupportsMultiReplaceString(model)) {
53-
lookForTools.add(ToolName.MultiReplaceString);
54-
}
55-
}
56-
5743
lookForTools.add(ToolName.EditNotebook);
5844
lookForTools.add(ToolName.GetNotebookSummary);
5945
lookForTools.add(ToolName.RunNotebookCell);
@@ -117,6 +103,8 @@ export class NotebookEditorIntentInvocation extends EditCode2IntentInvocation {
117103
super(intent, location, endpoint, request, intentOptions, instantiationService, codeMapperService, envService, promptPathRepresentationService, endpointProvider, workspaceService, toolsService, configurationService, editLogService, commandService, telemetryService, notebookService, logService);
118104
}
119105

106+
protected override prompt = NotebookInlinePrompt;
107+
120108
public override async getAvailableTools(): Promise<vscode.LanguageModelToolInformation[]> {
121109
return getTools(this.instantiationService, this.request);
122110
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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

Comments
 (0)