import type { Message } from 'ai'; import React, { useState } from 'react'; import { classNames } from '~/utils/classNames'; import { AssistantMessage, getAnnotationsTokensUsage } from './AssistantMessage'; import { UserMessage } from './UserMessage'; import { useLocation } from '@remix-run/react'; import { db, chatId } from '~/lib/persistence/useChatHistory'; import { forkChat } from '~/lib/persistence/db'; import { toast } from 'react-toastify'; import WithTooltip from '~/components/ui/Tooltip'; import { assert, sendCommandDedicatedClient } from "~/lib/replay/ReplayProtocolClient"; interface MessagesProps { id?: string; className?: string; isStreaming?: boolean; messages?: Message[]; } interface ProjectContents { content: string; // base64 encoded } const gProjectContentsByMessageId = new Map(); export function saveProjectContents(messageId: string, contents: ProjectContents) { gProjectContentsByMessageId.set(messageId, contents); } // The rewind button is not fully implemented yet. const EnableRewindButton = false; export const Messages = React.forwardRef((props: MessagesProps, ref) => { const { id, isStreaming = false, messages = [] } = props; const getLastMessageProjectContents = (index: number) => { // The message index is for the model response, and the project // contents will be associated with the last message present when // the user prompt was sent to the model. So look back two messages // for the previous contents. if (index < 2) { return undefined; } const previousMessage = messages[index - 2]; return gProjectContentsByMessageId.get(previousMessage.id); }; return (
{messages.length > 0 ? messages.map((message, index) => { const { role, content, id: messageId } = message; const isUserMessage = role === 'user'; const isFirst = index === 0; const isLast = index === messages.length - 1; return (
{isUserMessage && (
)}
{isUserMessage ? ( ) : ( )}
{!isUserMessage && messageId && getLastMessageProjectContents(index) && EnableRewindButton && (
)}
); }) : null} {isStreaming && (
)}
); });