Path: blob/main/extensions/copilot/src/extension/prompts/node/agent/agentConversationHistory.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, Chunk, PrioritizedList, PromptElement, PromptSizing, UserMessage } from '@vscode/prompt-tsx';6import { IResultMetadata, Turn } from '../../../prompt/common/conversation';7import { IBuildPromptContext } from '../../../prompt/common/intents';8import { Tag } from '../base/tag';9import { ChatVariables } from '../panel/chatVariables';10import { ChatToolCalls } from '../panel/toolCalling';11import { EditedFileEvents, renderedMessageToTsxChildren } from './agentPrompt';1213export interface AgentUserMessageInHistoryProps extends BasePromptElementProps {14readonly turn: Turn;15}1617export class AgentUserMessageInHistory extends PromptElement<AgentUserMessageInHistoryProps> {18constructor(19props: AgentUserMessageInHistoryProps,20) {21super(props);22}2324override async render(state: void, sizing: PromptSizing) {25const turn = this.props.turn;26return <UserMessage>27{turn.promptVariables && <ChatVariables flexGrow={1} priority={898} chatVariables={turn.promptVariables} isAgent={true} omitReferences />}28{turn.editedFileEvents?.length &&29<Tag name='context'>30<EditedFileEvents flexGrow={2} editedFileEvents={turn.editedFileEvents} />31</Tag>}32<Tag name='userRequest'>{turn.request.message}</Tag>33</UserMessage>;34}35}3637export interface AgentConversationHistoryProps extends BasePromptElementProps {38readonly priority: number;39readonly promptContext: IBuildPromptContext;40}4142/**43* Agent conversation history for when summarization/cache breakpoints are disabled.44*/45export class AgentConversationHistory extends PromptElement<AgentConversationHistoryProps> {46override async render(state: void, sizing: PromptSizing) {47const history: PromptElement[] = [];48const contextHistory = this.props.promptContext.history;49for (const [i, turn] of contextHistory.entries()) {50const metadata = turn.responseChatResult?.metadata as IResultMetadata | undefined;5152if (metadata?.renderedUserMessage) {53history.push(<UserMessage><Chunk>{renderedMessageToTsxChildren(metadata.renderedUserMessage, false)}</Chunk></UserMessage>);54} else {55history.push(<AgentUserMessageInHistory turn={turn} />);56}5758if (Array.isArray(metadata?.toolCallRounds) && metadata.toolCallRounds?.length > 0) {59// If a tool call limit is exceeded, the tool call from this turn will60// have been aborted and any result should be found in the next turn.61const toolCallResultInNextTurn = metadata.maxToolCallsExceeded;62let toolCallResults = metadata.toolCallResults;63if (toolCallResultInNextTurn) {64const nextMetadata = contextHistory.at(i + 1)?.responseChatResult?.metadata as IResultMetadata | undefined;65const mergeFrom = i === contextHistory.length - 1 ? this.props.promptContext.toolCallResults : nextMetadata?.toolCallResults;66toolCallResults = { ...toolCallResults, ...mergeFrom };67}6869history.push(<ChatToolCalls70promptContext={this.props.promptContext}71toolCallRounds={metadata.toolCallRounds}72toolCallResults={toolCallResults}73isHistorical={!(toolCallResultInNextTurn && i === contextHistory.length - 1)}74/>);75} else if (turn.responseMessage) {76history.push(<AssistantMessage>{turn.responseMessage?.message}</AssistantMessage>);77}78}7980return (<PrioritizedList priority={this.props.priority} descending={false}>{history}</PrioritizedList>);81}82}8384