Path: blob/main/extensions/copilot/src/extension/prompts/node/panel/newNotebook.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 { AssistantMessage, BasePromptElementProps, PromptElement, PromptPiece, PromptSizing, Raw, SystemMessage, UserMessage } from '@vscode/prompt-tsx';6import type { Uri } from 'vscode';7import { getTextPart } from '../../../../platform/chat/common/globalStringUtils';8import { IChatEndpoint } from '../../../../platform/networking/common/networking';9import { INotebookSection } from '../../../../util/common/notebooks';10import { isNonEmptyArray } from '../../../../util/vs/base/common/arrays';11import { IBuildPromptContext } from '../../../prompt/common/intents';12import { CopilotIdentityRules } from '../base/copilotIdentity';13import { ResponseTranslationRules } from '../base/responseTranslationRules';14import { LegacySafetyRules } from '../base/safetyRules';15import { JupyterNotebookRules } from '../notebook/commonPrompts';16import { ChatToolReferences, ChatVariablesAndQuery } from './chatVariables';17import { EditorIntegrationRules } from './editorIntegrationRules';18import { CodeBlock } from './safeElements';1920export interface NewNotebookPlanningPromptProps extends BasePromptElementProps {21promptContext: IBuildPromptContext;22endpoint: IChatEndpoint;23}2425export interface NewNotebookPlanningPromptState {26}2728export class NewNotebookPlanningPrompt extends PromptElement<NewNotebookPlanningPromptProps, NewNotebookPlanningPromptState> {29override async prepare(): Promise<NewNotebookPlanningPromptState> {30return {};31}3233override render(state: NewNotebookPlanningPromptState, sizing: PromptSizing): PromptPiece<any, any> | undefined {34return (35<>36<><SystemMessage priority={1000}>37You are an AI that creates a detailed content outline for a Jupyter notebook on a given topic.<br />38<CopilotIdentityRules />39<LegacySafetyRules />40<EditorIntegrationRules />41<ResponseTranslationRules />42<br />43Additional Rules<br />44DO NOT include Introduction or Conclusion section in the outline!<br />45Focus only on sections that will need code!<br />46{[47'',48'Generate the outline as two parts:',49'- First part is markdown bullet list of section titles',50'- Second part is the JSON data that will validate against this JSON schema, wrap the response in code block. We assume that a code block begins with \`\`\`[optionally the language] and ends with \`\`\`',51'',52'The JSON schema is:',53'{',54' "$schema": "http://json-schema.org/draft-07/schema#",',55' "type": "object",',56' "properties": {',57' "description": {',58' "type": "string"',59' },',60' "sections": {',61' "type": "array",',62' "items": {',63' "type": "object",',64' "properties": {',65' "title": {',66' "type": "string"',67' },',68' "content": {',69' "type": "string"',70' }',71' },',72' "required": ["title", "content"]',73' }',74' }',75' },',76' "required": ["sections"]',77'}'78].join('\n')}79{[80'',81'Examples:',82'',83'Below you will find a set of examples of what you should respond with. Please follow these examples as closely as possible.',84'',85'## Valid notebook creation question',86'',87'user: Creating Random Arrays with Numpy',88'',89'assistant: Here\'s an outline for a Jupyter notebook that creates Random Arrays with Numpy:',90'',91'* **Import Required Libraries**',92'* **Create Random Arrays**',93'* **Seed the Random Number Generator**',94'* **Generate Random Integers**',95'',96'\`\`\`json',97'{',98' "description": "A Jupyter notebook that creates Random Arrays with Numpy.",',99' "sections": [',100' {',101' "title": "Import Required Libraries",',102' "content": "Import the necessary libraries, including NumPy."',103' },',104' {',105' "title": "Create Random Arrays",',106' "content": "Use NumPy to create random arrays of various shapes and sizes, including 1D, 2D, and 3D arrays."',107' },',108' {',109' "title": "Seed the Random Number Generator",',110' "content": "Use the seed() function to seed the random number generator for reproducibility."',111' },',112' {',113' "title": "Generate Random Integers",',114' "content": "Use the randint() function to generate random integers within a specified range."',115' }',116' ]',117'}',118'\`\`\`'].join('\n')119}120</SystemMessage></>121122<ChatToolReferences priority={899} flexGrow={2} promptContext={this.props.promptContext} embeddedInsideUserMessage={false} />123{this.props.promptContext.chatVariables && Object.keys(this.props.promptContext.chatVariables).length > 0 ? (124<ChatVariablesAndQuery flexGrow={2} priority={900} chatVariables={this.props.promptContext.chatVariables} query={this.props.promptContext.query} embeddedInsideUserMessage={false} />125) : (126<UserMessage priority={900}>127{this.props.promptContext.query}128</UserMessage >129)}130</>131);132}133}134135export interface NewNotebookCodeGenerationPromptProps extends BasePromptElementProps {136history?: readonly Raw.ChatMessage[];137description: string;138section: INotebookSection;139existingCode: string;140languageId: string;141uri: Uri;142}143144export interface NewNotebookCodeGenerationPromptState {145}146147export class NewNotebookCodeGenerationPrompt extends PromptElement<NewNotebookCodeGenerationPromptProps, NewNotebookCodeGenerationPromptState> {148override async prepare(): Promise<NewNotebookPlanningPromptState> {149return {};150}151override render(state: NewNotebookCodeGenerationPromptState, sizing: PromptSizing): PromptPiece<any, any> | undefined {152return (153<>154<>155{isNonEmptyArray(this.props.history) && <GenerateNotebookConversationHistory messages={this.props.history} />}156<SystemMessage priority={1000}>157You are an AI that writes Python code for a single section of a Jupyter notebook.<br />158<CopilotIdentityRules />159<LegacySafetyRules />160<ResponseTranslationRules />161<JupyterNotebookRules />162When dealing with Jupyter Notebook, do not generate CELL INDEX in the code blocks in your answer, it is only used to help you understand the context.<br />163164Your output should be valid Python code with inline comments.<br />165You should return the code directly without any explantion.<br />166You should not print message to explain the code or purpose of the code.<br />167You should return the code directly, without wrapping it inside \`\`\`.<br />168169Please make sure that the new code is syntactically valid Python code. It can be validated by running it in a Python interpreter.<br />170For example, it should pass the validation through builtin module codeop \`codeop.compile_command(statement)\`.<br />171</SystemMessage>172<UserMessage priority={900}>173Overall topic of the notebook: {this.props.description}<br />174Title of the notebook section: {this.props.section.title}<br />175Description of the notebok section: {this.props.section.content}<br />176Given this information, write all the code for this section and this section only.<br />177The request to generate the outline of the notebook is already completed.<br />178Here is the request details for the outline generation:<br />179<br />180Code in the notebook so far:<br />181<CodeBlock uri={this.props.uri} languageId={this.props.languageId} code={this.props.existingCode} />182<br />183Please make sure the new code you generate works fine with the code above.<br />184</UserMessage>185</>186</>187);188}189}190interface GenerateNotebookConversationHistoryProps extends BasePromptElementProps {191messages: readonly Raw.ChatMessage[];192}193194class GenerateNotebookConversationHistory extends PromptElement<GenerateNotebookConversationHistoryProps> {195override render(state: void, sizing: PromptSizing): PromptPiece<any, any> | undefined {196const history: (UserMessage | AssistantMessage | SystemMessage)[] = [];197198for (const curr of this.props.messages) {199switch (curr.role) {200case Raw.ChatRole.User:201history.push(<UserMessage priority={800}>{getTextPart(curr.content)}</UserMessage>);202break;203case Raw.ChatRole.Assistant:204history.push(<AssistantMessage priority={800}>{getTextPart(curr.content)}</AssistantMessage>);205break;206case Raw.ChatRole.System:207history.push(<SystemMessage priority={100}>{getTextPart(curr.content)}</SystemMessage>);208break;209default:210break;211}212}213214return (<>{history}</>);215}216}217218219export interface NewNotebookCodeImprovementPromptProps extends BasePromptElementProps {220description: string;221section: INotebookSection;222existingCode: string;223code: string;224languageId: string;225uri: Uri;226}227228export interface NewNotebookCodeImprovementPromptState {229}230231export class NewNotebookCodeImprovementPrompt extends PromptElement<NewNotebookCodeImprovementPromptProps, NewNotebookCodeImprovementPromptState> {232override async prepare(): Promise<NewNotebookCodeImprovementPromptState> {233return {};234}235override render(state: NewNotebookCodeImprovementPromptState, sizing: PromptSizing): PromptPiece<any, any> | undefined {236return (237<>238<>239<SystemMessage priority={1000}>240You are an AI that improves Python code with respect to readability and performance for a single section of a Jupyter notebook.<br />241<CopilotIdentityRules />242<LegacySafetyRules />243<ResponseTranslationRules />244You MUST return Python code as your answer.<br />245DO NOT explain in inline comments for your the improvements.<br />246You should not print messages to explain the code or purpose of the code.<br />247Make sure the new code you generate works fine with the code above.<br />248Make sure if a module is already imported in the code above, it can be used in the new code directly without importing it again. For the same reason, if a variable is defined above, it can be used in new code as well. <br />249Make sure to return the code only - don't give an explanation of the improvements.<br />250</SystemMessage>251<UserMessage priority={900}>252Overall topic of the notebook: {this.props.description}<br />253Title of the notebook section: {this.props.section.title}<br />254Description of the notebook section: {this.props.section.content}<br />255Code in the notebook so far:<br />256<br />257<CodeBlock uri={this.props.uri} languageId={this.props.languageId} code={this.props.existingCode} />258<br />259Given this information, suggest improvements for the following code:<br />260<br />261{this.props.code}<br />262<br />263</UserMessage>264</>265</>266);267}268}269270271