Skip to content

Commit

Permalink
fix: save output files after receiving them on search results event (#…
Browse files Browse the repository at this point in the history
…656)

* fix: save output files after receiving them on search results event

* fix: accent color on show steps button

* refactor: early return to improve readability

* feat: increase accesibility of images
  • Loading branch information
tomtobac authored Aug 14, 2024
1 parent 86e1ce0 commit 3b89f69
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 96 deletions.
28 changes: 14 additions & 14 deletions src/interfaces/assistants_web/src/components/MarkdownImage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,33 +27,33 @@ export const MarkdownImage: React.FC<Props> = ({ node }) => {

if (outputFiles[fileName]) {
return <B64Image data={outputFiles[fileName].data} caption={caption} />;
} else {
return (
<>
<img className="w-full" src={fileName} alt={caption} />
{caption && (
<Text as="span" styleAs="caption" className="mb-2 text-mushroom-300">
{caption}
</Text>
)}
</>
);
}

return (
<figure>
<img className="w-full" src={fileName} alt={caption} />
{caption && (
<Text as="figcaption" styleAs="caption" className="mb-2 text-mushroom-300">
{caption}
</Text>
)}
</figure>
);
};

export const B64Image: React.FC<{ data: string; caption?: string }> = ({ data, caption }) => {
return (
<>
<figure>
<img className="w-full dark:invert" src={`data:image/png;base64,${data}`} alt={caption} />
{caption && (
<Text
as="span"
as="figcaption"
styleAs="caption"
className="mb-2 text-mushroom-300 dark:bg-[#3D3B36] dark:text-mushroom-950"
>
{caption}
</Text>
)}
</>
</figure>
);
};
152 changes: 79 additions & 73 deletions src/interfaces/assistants_web/src/components/MessageContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,9 @@ export const MessageContent: React.FC<Props> = ({ isLast, message, onRetry }) =>
const isAborted = isAbortedMessage(message);
const isTypingOrFulfilledMessage = isFulfilledOrTypingMessage(message);

let content: React.ReactNode = null;

if (isUserError) {
content = (
<>
return (
<MessageWrapper>
<Text>{message.text}</Text>
<MessageInfo type="error">
{message.error}
Expand All @@ -49,11 +47,13 @@ export const MessageContent: React.FC<Props> = ({ isLast, message, onRetry }) =>
</button>
)}
</MessageInfo>
</>
</MessageWrapper>
);
} else if (isUser) {
content = (
<>
}

if (isUser) {
return (
<MessageWrapper>
<Markdown text={message.text} renderRawHtml={false} />
{message.files && message.files.length > 0 && (
<div className="flex flex-wrap gap-2 py-2">
Expand All @@ -62,84 +62,79 @@ export const MessageContent: React.FC<Props> = ({ isLast, message, onRetry }) =>
))}
</div>
)}
</>
</MessageWrapper>
);
} else if (isLoading) {
}

if (isLoading) {
const hasLoadingMessage = message.text.length > 0;
content = (
<Text className={cn('flex min-w-0 text-volcanic-400')} as="span">
{hasLoadingMessage && (
<Transition
as="div"
appear={true}
show={true}
enterFrom="opacity-0"
enterTo="opacity-full"
enter="transition-opacity ease-in-out duration-500"
>
{message.text}
</Transition>
)}
{!hasLoadingMessage && (
<span className="w-max">
<div className="animate-typing-ellipsis overflow-hidden whitespace-nowrap pr-1">
...
</div>
</span>
)}
</Text>
return (
<MessageWrapper>
<Text className={cn('flex min-w-0 text-volcanic-400')} as="span">
{hasLoadingMessage && (
<Transition
as="div"
appear={true}
show={true}
enterFrom="opacity-0"
enterTo="opacity-full"
enter="transition-opacity ease-in-out duration-500"
>
{message.text}
</Transition>
)}
{!hasLoadingMessage && (
<span className="w-max">
<div className="animate-typing-ellipsis overflow-hidden whitespace-nowrap pr-1">
...
</div>
</span>
)}
</Text>
</MessageWrapper>
);
} else if (isBotError) {
content = (
<>
}

if (isBotError) {
return (
<MessageWrapper>
{message.text.length > 0 ? (
<Markdown text={message.text} />
) : (
<Text className={cn('text-volcanic-400')}>{BOT_ERROR_MESSAGE}</Text>
)}
<MessageInfo type="error">{message.error}</MessageInfo>
</>
);
} else {
const hasCitations =
isTypingOrFulfilledMessage && message.citations && message.citations.length > 0;
content = (
<>
<Markdown
className={cn({
'text-volcanic-400': isAborted,
})}
text={message.text}
customComponents={{
img: MarkdownImage as any,
cite: CitationTextHighlighter as any,
table: DataTable as any,
}}
renderLaTex={!hasCitations}
/>
{isAborted && (
<MessageInfo>
This generation was stopped.{' '}
{isLast && isAborted && (
<button className="underline underline-offset-1" type="button" onClick={onRetry}>
Retry?
</button>
)}
</MessageInfo>
)}
</>
</MessageWrapper>
);
}

const hasCitations =
isTypingOrFulfilledMessage && message.citations && message.citations.length > 0;
return (
<div className="flex w-full flex-col justify-center gap-y-1 py-1">
<Text
as="div"
className="flex flex-col gap-y-1 whitespace-pre-wrap [overflow-wrap:anywhere] md:max-w-4xl"
>
{content}
</Text>
</div>
<MessageWrapper>
<Markdown
className={cn({
'text-volcanic-400': isAborted,
})}
text={message.text}
customComponents={{
img: MarkdownImage as any,
cite: CitationTextHighlighter as any,
table: DataTable as any,
}}
renderLaTex={!hasCitations}
/>
{isAborted && (
<MessageInfo>
This generation was stopped.{' '}
{isLast && isAborted && (
<button className="underline underline-offset-1" type="button" onClick={onRetry}>
Retry?
</button>
)}
</MessageInfo>
)}
</MessageWrapper>
);
};

Expand All @@ -157,3 +152,14 @@ const MessageInfo = ({
<Text as="span">{children}</Text>
</div>
);

const MessageWrapper = ({ children }: PropsWithChildren) => (
<div className="flex w-full flex-col justify-center gap-y-1 py-1">
<Text
as="div"
className="flex flex-col gap-y-1 whitespace-pre-wrap [overflow-wrap:anywhere] md:max-w-4xl"
>
{children}
</Text>
</div>
);
7 changes: 2 additions & 5 deletions src/interfaces/assistants_web/src/components/MessageRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,8 @@ const MessageRow = forwardRef<HTMLDivElement, Props>(function MessageRowInternal
iconName="list"
className="grid place-items-center rounded hover:bg-mushroom-900 dark:hover:bg-volcanic-200"
iconClassName={cn(
'text-volcanic-300 group-hover/icon-button:fill-mushroom-300',
'dark:fill-marble-800 dark:group-hover/icon-button:fill-marble-800',
{
'hidden md:invisible md:flex': !isFulfilledMessage(message),
}
'text-volcanic-300 fill-volcanic-300 group-hover/icon-button:fill-mushroom-300',
'dark:fill-marble-800 dark:group-hover/icon-button:fill-marble-800'
)}
onClick={() => setIsStepsExpanded((prevIsExpanded) => !prevIsExpanded)}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ type AsElement =
| 'li'
| 'label'
| 'pre'
| 'kbd';
| 'kbd'
| 'figcaption';
type StyleAs = keyof typeof STYLE_LEVEL_TO_CLASSES;

type TextProps<T extends AsElement> = {
Expand Down
7 changes: 4 additions & 3 deletions src/interfaces/assistants_web/src/hooks/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
FinishReason,
StreamEnd,
StreamEvent,
StreamToolCallsChunk,
StreamToolCallsGeneration,
isCohereNetworkError,
isStreamError,
Expand Down Expand Up @@ -254,6 +253,8 @@ export const useChat = (config?: { onSend?: (msg: string) => void }) => {
mapDocuments(documents);
documentsMap = { ...documentsMap, ...newDocumentsMap };
outputFiles = { ...outputFiles, ...newOutputFilesMap };
saveOutputFiles({ ...savedOutputFiles, ...outputFiles });

// we are only interested in web_search results
// ignore search results of pyhton interpreter tool
if (
Expand All @@ -272,7 +273,7 @@ export const useChat = (config?: { onSend?: (msg: string) => void }) => {

case StreamEvent.TOOL_CALLS_CHUNK: {
setIsStreamingToolEvents(true);
const data = eventData.data as StreamToolCallsChunk;
const data = eventData.data;

// Initiate an empty tool event if one doesn't already exist at the current index
const toolEvent: StreamToolCallsGeneration = toolEvents[currentToolEventIndex] ?? {
Expand Down Expand Up @@ -338,7 +339,7 @@ export const useChat = (config?: { onSend?: (msg: string) => void }) => {
}

case StreamEvent.TOOL_CALLS_GENERATION: {
const data = eventData.data as StreamToolCallsGeneration;
const data = eventData.data;

if (toolEvents[currentToolEventIndex]) {
toolEvents[currentToolEventIndex] = data;
Expand Down

0 comments on commit 3b89f69

Please sign in to comment.