Skip to content

Commit

Permalink
add streaming of artifacts
Browse files Browse the repository at this point in the history
  • Loading branch information
HenryHengZJ committed Sep 15, 2024
1 parent a278b00 commit 6a9645d
Show file tree
Hide file tree
Showing 11 changed files with 149 additions and 15 deletions.
2 changes: 2 additions & 0 deletions dist/components/Bot.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export type IAgentReasoning = {
agentName?: string;
messages?: string[];
usedTools?: any[];
artifacts?: FileUpload[];
sourceDocuments?: any[];
instructions?: string;
nextAgent?: string;
Expand All @@ -56,6 +57,7 @@ export type MessageType = {
sourceDocuments?: any;
fileAnnotations?: any;
fileUploads?: Partial<FileUpload>[];
artifacts?: Partial<FileUpload>[];
agentReasoning?: IAgentReasoning[];
usedTools?: any[];
action?: IAction | null;
Expand Down
2 changes: 1 addition & 1 deletion dist/components/Bot.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 5 additions & 0 deletions dist/components/bubbles/AgentReasoningBubble.d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { FileUpload } from '../Bot';
type Props = {
apiHost?: string;
chatflowid: string;
chatId: string;
agentName: string;
agentMessage: string;
agentArtifacts?: FileUpload[];
backgroundColor?: string;
textColor?: string;
fontSize?: number;
Expand Down
2 changes: 1 addition & 1 deletion dist/components/bubbles/AgentReasoningBubble.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/components/bubbles/BotBubble.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/web.js

Large diffs are not rendered by default.

22 changes: 18 additions & 4 deletions src/components/Bot.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import { cancelAudioRecording, startAudioRecording, stopAudioRecording } from '@
import { LeadCaptureBubble } from '@/components/bubbles/LeadCaptureBubble';
import { removeLocalStorageChatHistory, getLocalStorageChatflow, setLocalStorageChatflow, setCookie, getCookie } from '@/utils';
import { cloneDeep } from 'lodash';
import { EventStreamContentType, fetchEventSource } from '@microsoft/fetch-event-source';
import { fetchEventSource } from '@microsoft/fetch-event-source';

export type FileEvent<T = EventTarget> = {
target: T;
Expand Down Expand Up @@ -65,6 +65,7 @@ export type IAgentReasoning = {
agentName?: string;
messages?: string[];
usedTools?: any[];
artifacts?: FileUpload[];
sourceDocuments?: any[];
instructions?: string;
nextAgent?: string;
Expand Down Expand Up @@ -92,6 +93,7 @@ export type MessageType = {
sourceDocuments?: any;
fileAnnotations?: any;
fileUploads?: Partial<FileUpload>[];
artifacts?: Partial<FileUpload>[];
agentReasoning?: IAgentReasoning[];
usedTools?: any[];
action?: IAction | null;
Expand Down Expand Up @@ -230,9 +232,6 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
let bottomSpacer: HTMLDivElement | undefined;
let botContainer: HTMLDivElement | undefined;

// Extract sourceDocsTitle directly from props
const sourceDocsTitle = props.sourceDocsTitle;

const [userInput, setUserInput] = createSignal('');
const [loading, setLoading] = createSignal(false);
const [sourcePopupOpen, setSourcePopupOpen] = createSignal(false);
Expand Down Expand Up @@ -411,6 +410,16 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
});
};

const updateLastMessageArtifacts = (artifacts: FileUpload[]) => {
setMessages((prevMessages) => {
const allMessages = [...cloneDeep(prevMessages)];
if (allMessages[allMessages.length - 1].type === 'userMessage') return allMessages;
allMessages[allMessages.length - 1].artifacts = artifacts;
addChatMessage(allMessages);
return allMessages;
})
}

const updateLastMessageAction = (action: IAction) => {
setMessages((data) => {
const updated = data.map((item, i) => {
Expand Down Expand Up @@ -517,6 +526,9 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
case 'action':
updateLastMessageAction(payload.data);
break;
case 'artifacts':
updateLastMessageArtifacts(payload.data);
break;
case 'metadata':
updateMetadata(payload.data, input);
break;
Expand Down Expand Up @@ -663,6 +675,7 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
fileAnnotations: data?.fileAnnotations,
agentReasoning: data?.agentReasoning,
action: data?.action,
artifacts: data?.artifacts,
type: 'apiMessage' as messageType,
feedback: null,
};
Expand Down Expand Up @@ -821,6 +834,7 @@ export const Bot = (botProps: BotProps & { class?: string }) => {
if (message.fileUploads) chatHistory.fileUploads = message.fileUploads;
if (message.agentReasoning) chatHistory.agentReasoning = message.agentReasoning;
if (message.action) chatHistory.action = message.action;
if (message.artifacts) chatHistory.artifacts = message.artifacts;
return chatHistory;
})
: [{ message: props.welcomeMessage ?? defaultWelcomeMessage, type: 'apiMessage' }];
Expand Down
66 changes: 64 additions & 2 deletions src/components/bubbles/AgentReasoningBubble.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
import { onMount } from 'solid-js';
import { For, onMount } from 'solid-js';
import { Marked } from '@ts-stack/markdown';
import { FileUpload } from '../Bot';
import { cloneDeep } from 'lodash';

type Props = {
apiHost?: string;
chatflowid: string;
chatId: string
agentName: string;
agentMessage: string;
agentArtifacts?: FileUpload[];
backgroundColor?: string;
textColor?: string;
fontSize?: number;
Expand All @@ -13,7 +19,7 @@ const defaultBackgroundColor = '#f7f8ff';
const defaultTextColor = '#303235';
const defaultFontSize = 16;

Marked.setOptions({ isNoP: true });
Marked.setOptions({ isNoP: true, sanitize: true });

export const AgentReasoningBubble = (props: Props) => {
let botMessageEl: HTMLDivElement | undefined;
Expand All @@ -27,8 +33,64 @@ export const AgentReasoningBubble = (props: Props) => {
}
});

const agentReasoningArtifacts = (artifacts: FileUpload[]) => {
const newArtifacts = cloneDeep(artifacts)
for (let i = 0; i < newArtifacts.length; i++) {
const artifact = newArtifacts[i]
if (artifact && (artifact.type === 'png' || artifact.type === 'jpeg')) {
const data = artifact.data as string
newArtifacts[i].data = `${props.apiHost}/api/v1/get-upload-file?chatflowId=${props.chatflowid}&chatId=${props.chatId}&fileName=${data.replace(
'FILE-STORAGE::',
''
)}`
}
}
return newArtifacts
}

const renderArtifacts = (item: Partial<FileUpload>) => {
if (item.type === 'png' || item.type === 'jpeg') {
const src = item.data as string;
return (
<div class="flex items-center justify-center max-w-[128px] mr-[10px] p-0 m-0">
<img class="w-full h-full bg-cover" src={src} />
</div>
);
} else if (item.type === 'html') {
const src = (item.data as string);
return (
<div class="mt-2">
<div innerHTML={src}></div>
</div>
);
} else {
const src = item.data as string;
return (
<span
innerHTML={Marked.parse(src)}
class="prose"
style={{
'background-color': props.backgroundColor ?? defaultBackgroundColor,
color: props.textColor ?? defaultTextColor,
'border-radius': '6px',
'font-size': props.fontSize ? `${props.fontSize}px` : `${defaultFontSize}px`,
}}
/>
);
}
};

return (
<div class="mb-6">
{props.agentArtifacts && (
<div class="flex flex-row items-start flex-wrap w-full gap-2">
<For each={agentReasoningArtifacts(props.agentArtifacts)}>
{(item) => {
return item !== null ? <>{renderArtifacts(item)}</> : null
}}
</For>
</div>
)}
{props.agentMessage && (
<span
ref={botMessageEl}
Expand Down
Loading

0 comments on commit 6a9645d

Please sign in to comment.