Path: blob/main/extensions/copilot/src/extension/conversation/vscode-node/languageModelAccessPrompt.tsx
13399 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*--------------------------------------------------------------------------------------------*/456import { AssistantMessage, PromptElement, PromptElementProps, SystemMessage, ToolMessage, UserMessage } from '@vscode/prompt-tsx';7import * as vscode from 'vscode';8import { LanguageModelTextPart } from 'vscode';9import { CustomDataPartMimeTypes } from '../../../platform/endpoint/common/endpointTypes';10import { decodeStatefulMarker, StatefulMarkerContainer } from '../../../platform/endpoint/common/statefulMarkerContainer';11import { ThinkingDataContainer } from '../../../platform/endpoint/common/thinkingDataContainer';12import { SafetyRules } from '../../prompts/node/base/safetyRules';13import { EditorIntegrationRules } from '../../prompts/node/panel/editorIntegrationRules';14import { imageDataPartToTSX, ToolResult } from '../../prompts/node/panel/toolCalling';15import { isImageDataPart } from '../common/languageModelChatMessageHelpers';1617export type Props = PromptElementProps<{18noSafety: boolean;19messages: Array<vscode.LanguageModelChatMessage | vscode.LanguageModelChatMessage2>;20}>;2122export class LanguageModelAccessPrompt extends PromptElement<Props> {23async render() {2425const systemMessages: string[] = [];26const chatMessages: (UserMessage | AssistantMessage)[] = [];2728for (const message of this.props.messages) {29if (message.role === vscode.LanguageModelChatMessageRole.System) {30// Filter out DataPart since it does not share the same value type and does not have callId, function, etc.31const filteredContent = message.content.filter(part => !(part instanceof vscode.LanguageModelDataPart));32systemMessages.push(filteredContent33.filter(part => part instanceof vscode.LanguageModelTextPart)34.map(part => part.value).join(''));3536} else if (message.role === vscode.LanguageModelChatMessageRole.Assistant) {37const statefulMarkerPart = message.content.find(part => part instanceof vscode.LanguageModelDataPart && part.mimeType === CustomDataPartMimeTypes.StatefulMarker) as vscode.LanguageModelDataPart | undefined;38const statefulMarker = statefulMarkerPart && decodeStatefulMarker(statefulMarkerPart.data);39const filteredContent = message.content.filter(part => !(part instanceof vscode.LanguageModelDataPart));40// There should only be one string part per message41const content = filteredContent.find(part => part instanceof LanguageModelTextPart);42const toolCalls = filteredContent.filter(part => part instanceof vscode.LanguageModelToolCallPart);43const thinking = filteredContent.find(part => part instanceof vscode.LanguageModelThinkingPart);4445const statefulMarkerElement = statefulMarker && <StatefulMarkerContainer statefulMarker={statefulMarker} />;46const thinkingElement = thinking && thinking.id && <ThinkingDataContainer thinking={{ id: thinking.id, text: thinking.value, metadata: thinking.metadata }} />;47chatMessages.push(<AssistantMessage name={message.name} toolCalls={toolCalls.map(tc => ({ id: tc.callId, type: 'function', function: { name: tc.name, arguments: JSON.stringify(tc.input) } }))}>{statefulMarkerElement}{content?.value}{thinkingElement}</AssistantMessage>);48} else if (message.role === vscode.LanguageModelChatMessageRole.User) {49for (const part of message.content) {50if (part instanceof vscode.LanguageModelToolResultPart2 || part instanceof vscode.LanguageModelToolResultPart) {51chatMessages.push(52<ToolMessage toolCallId={part.callId}>53<ToolResult content={part.content} toolCallId={part.callId} />54</ToolMessage>55);56} else if (isImageDataPart(part)) {57const imageElement = await imageDataPartToTSX(part);58chatMessages.push(<UserMessage priority={0}>{imageElement}</UserMessage>);59} else if (part instanceof vscode.LanguageModelTextPart) {60chatMessages.push(<UserMessage name={message.name}>{part.value}</UserMessage>);61}62}63}64}6566return (67<>68<SystemMessage>69{this.props.noSafety70// Only custom system message71? systemMessages72// Our and custom system message73: <>74<SafetyRules />75<EditorIntegrationRules />76<br />77{systemMessages.join('\n')}78</>}79</SystemMessage>80{chatMessages}81</>82);83}84}858687