Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Co Edition Bouyah! #9006

Draft
wants to merge 9 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 19 additions & 5 deletions front/components/assistant/conversation/AgentMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import type {
RetrievalActionType,
UserType,
WebsearchActionType,
WithRank,
WorkspaceType,
} from "@dust-tt/types";
import {
Expand Down Expand Up @@ -67,8 +68,10 @@ import {
mentionDirective,
} from "@app/components/markdown/MentionBlock";
import {
getInteractiveDocumentPlugin,
getVisualizationPlugin,
sanitizeVisualizationContent,
interactiveDocumentDirective,
sanitizeContent,
visualizationDirective,
} from "@app/components/markdown/VisualizationBlock";
import { useEventSource } from "@app/hooks/useEventSource";
Expand All @@ -83,7 +86,7 @@ interface AgentMessageProps {
conversationId: string;
isInModal: boolean;
isLastMessage: boolean;
message: AgentMessageType;
message: WithRank<AgentMessageType>;
messageFeedback: ConversationMessageFeedbackSelectorProps;
owner: WorkspaceType;
user: UserType;
Expand Down Expand Up @@ -448,6 +451,8 @@ export function AgentMessage({
]);
const { configuration: agentConfiguration } = agentMessageToRender;

const messageVersion = message.rank * 1000 + message.version;

const additionalMarkdownComponents: Components = useMemo(
() => ({
visualization: getVisualizationPlugin(
Expand All @@ -456,14 +461,23 @@ export function AgentMessage({
conversationId,
message.sId
),
doc: getInteractiveDocumentPlugin(
agentConfiguration.sId,
messageVersion
),
sup: CiteBlock,
mention: MentionBlock,
}),
[owner, conversationId, message.sId, agentConfiguration.sId]
[owner, conversationId, message.sId, agentConfiguration.sId, messageVersion]
);

const additionalMarkdownPlugins: PluggableList = useMemo(
() => [mentionDirective, getCiteDirective(), visualizationDirective],
() => [
mentionDirective,
getCiteDirective(),
visualizationDirective,
interactiveDocumentDirective,
],
[]
);

Expand Down Expand Up @@ -582,7 +596,7 @@ export function AgentMessage({
}}
>
<Markdown
content={sanitizeVisualizationContent(agentMessage.content)}
content={sanitizeContent(agentMessage.content)}
isStreaming={
streaming && lastTokenClassification === "tokens"
}
Expand Down
153 changes: 78 additions & 75 deletions front/components/assistant/conversation/ConversationContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Page } from "@dust-tt/sparkle";
import { Page, ScrollArea } from "@dust-tt/sparkle";
import { useSendNotification } from "@dust-tt/sparkle";
import type {
AgentMention,
Expand Down Expand Up @@ -287,84 +287,87 @@ export function ConversationContainer({
description="Drag and drop your text files (txt, doc, pdf) and image files (jpg, png) here."
title="Attach files to the conversation"
>
<Transition
show={!!activeConversationId}
as={Fragment}
enter="transition-all duration-300 ease-out"
enterFrom="flex-none w-full h-0"
enterTo="flex flex-1 w-full"
leave="transition-all duration-0 ease-out"
leaveFrom="flex flex-1 w-full"
leaveTo="flex-none w-full h-0"
>
{activeConversationId ? (
<ConversationViewer
{/* //FIXME: Scroll area breaks the width */}
<ScrollArea className="h-screen">
<Transition
show={!!activeConversationId}
as={Fragment}
enter="transition-all duration-300 ease-out"
enterFrom="flex-none w-full h-0"
enterTo="flex flex-1 w-full"
leave="transition-all duration-0 ease-out"
leaveFrom="flex flex-1 w-full"
leaveTo="flex-none w-full h-0"
>
{activeConversationId ? (
<ConversationViewer
owner={owner}
user={user}
conversationId={activeConversationId}
// TODO(2024-06-20 flav): Fix extra-rendering loop with sticky mentions.
onStickyMentionsChange={onStickyMentionsChange}
/>
) : (
<div></div>
)}
</Transition>

<Transition
as={Fragment}
show={!activeConversationId}
enter="transition-opacity duration-100 ease-out"
enterFrom="opacity-0 min-h-[20vh]"
enterTo="opacity-100"
leave="transition-opacity duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0 min-h-[20vh]"
>
<div
id="assistant-input-header"
className="flex h-fit min-h-[20vh] w-full max-w-4xl flex-col justify-end gap-8 px-4 py-2"
>
<Page.Header title={greeting} />
<Page.SectionHeader title="Start a conversation" />
</div>
</Transition>

<FixedAssistantInputBar
owner={owner}
onSubmit={
activeConversationId ? handleSubmit : handleConversationCreation
}
stickyMentions={stickyMentions}
conversationId={activeConversationId}
/>

<Transition
show={!activeConversationId}
enter="transition-opacity duration-100 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0"
className={"flex w-full justify-center"}
>
<AssistantBrowserContainer
onAgentConfigurationClick={setInputbarMention}
setAssistantToMention={(assistant) => {
assistantToMention.current = assistant;
}}
owner={owner}
user={user}
conversationId={activeConversationId}
// TODO(2024-06-20 flav): Fix extra-rendering loop with sticky mentions.
onStickyMentionsChange={onStickyMentionsChange}
isBuilder={isBuilder}
/>
) : (
<div></div>
)}
</Transition>

<Transition
as={Fragment}
show={!activeConversationId}
enter="transition-opacity duration-100 ease-out"
enterFrom="opacity-0 min-h-[20vh]"
enterTo="opacity-100"
leave="transition-opacity duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0 min-h-[20vh]"
>
<div
id="assistant-input-header"
className="flex h-fit min-h-[20vh] w-full max-w-4xl flex-col justify-end gap-8 px-4 py-2"
>
<Page.Header title={greeting} />
<Page.SectionHeader title="Start a conversation" />
</div>
</Transition>

<FixedAssistantInputBar
owner={owner}
onSubmit={
activeConversationId ? handleSubmit : handleConversationCreation
}
stickyMentions={stickyMentions}
conversationId={activeConversationId}
/>

<Transition
show={!activeConversationId}
enter="transition-opacity duration-100 ease-out"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="transition-opacity duration-100 ease-out"
leaveFrom="opacity-100"
leaveTo="opacity-0"
className={"flex w-full justify-center"}
>
<AssistantBrowserContainer
onAgentConfigurationClick={setInputbarMention}
setAssistantToMention={(assistant) => {
assistantToMention.current = assistant;
}}
</Transition>

<ReachedLimitPopup
isOpened={planLimitReached}
onClose={() => setPlanLimitReached(false)}
subscription={subscription}
owner={owner}
isBuilder={isBuilder}
code="message_limit"
/>
</Transition>

<ReachedLimitPopup
isOpened={planLimitReached}
onClose={() => setPlanLimitReached(false)}
subscription={subscription}
owner={owner}
code="message_limit"
/>
</ScrollArea>
</DropzoneContainer>
);
}
71 changes: 64 additions & 7 deletions front/components/assistant/conversation/ConversationLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,23 @@
import type { SubscriptionType, WorkspaceType } from "@dust-tt/types";
import type {
LightWorkspaceType,
SubscriptionType,
WorkspaceType,
} from "@dust-tt/types";
import { useRouter } from "next/router";
import React, { useCallback, useEffect, useState } from "react";

import RootLayout from "@app/components/app/RootLayout";
import { AssistantDetails } from "@app/components/assistant/AssistantDetails";
import { CoEditionContainer } from "@app/components/assistant/conversation/co-edition/CoEditionContainer";
import {
CoEditionProvider,
useCoEditionContext,
} from "@app/components/assistant/conversation/co-edition/CoEditionContext";
import {
ResizableHandle,
ResizablePanel,
ResizablePanelGroup,
} from "@app/components/assistant/conversation/co-edition/Resizable";
import { ConversationErrorDisplay } from "@app/components/assistant/conversation/ConversationError";
import { ConversationTitle } from "@app/components/assistant/conversation/ConversationTitle";
import { FileDropProvider } from "@app/components/assistant/conversation/FileUploaderContext";
Expand Down Expand Up @@ -132,21 +146,64 @@ export default function ConversationLayout({
{conversationError ? (
<ConversationErrorDisplay error={conversationError} />
) : (
<>
<div className="h-full w-full">
<AssistantDetails
owner={owner}
assistantId={detailViewContent || null}
onClose={handleCloseModal}
/>
<FileDropProvider>
<GenerationContextProvider>

<CoEditionProvider>
<ConversationInnerLayout
conversationId={conversationId}
owner={owner}
>
{children}
</GenerationContextProvider>
</FileDropProvider>
</>
</ConversationInnerLayout>
</CoEditionProvider>
</div>
)}
</AppLayout>
</InputBarProvider>
</RootLayout>
);
}

interface ConversationInnerLayoutProps {
children: React.ReactNode;
conversationId: string | null;
owner: LightWorkspaceType;
}

function ConversationInnerLayout({
children,
conversationId,
owner,
}: ConversationInnerLayoutProps) {
const { state } = useCoEditionContext();

return (
<ResizablePanelGroup
direction="horizontal"
className="w-full rounded-lg border"
>
<FileDropProvider>
<GenerationContextProvider>
<ResizablePanel
minSize={20}
defaultSize={50}
className="overflow-y-visible border-none"
>
{children}
</ResizablePanel>
</GenerationContextProvider>
</FileDropProvider>
<ResizableHandle />
{conversationId && state.isVisible && (
<ResizablePanel minSize={20} defaultSize={50}>
<CoEditionContainer owner={owner} conversationId={conversationId} />
</ResizablePanel>
)}
</ResizablePanelGroup>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type {
MessageWithContentFragmentsType,
UserMessageNewEvent,
UserType,
WithRank,
WorkspaceType,
} from "@dust-tt/types";
import { isContentFragmentType } from "@dust-tt/types";
Expand Down Expand Up @@ -317,7 +318,7 @@ const ConversationViewer = React.forwardRef<
return (
<div
className={classNames(
"flex w-full max-w-4xl flex-1 flex-col justify-start gap-2 pb-4",
"flex h-full w-full max-w-4xl flex-1 flex-col justify-start gap-2 pb-4",
isFading ? "animate-fadeout" : "",
isInModal ? "pt-4" : "sm:px-4"
)}
Expand Down Expand Up @@ -377,8 +378,8 @@ export default ConversationViewer;
*/
const groupMessagesByType = (
messages: FetchConversationMessagesResponse[]
): MessageWithContentFragmentsType[][] => {
const groupedMessages: MessageWithContentFragmentsType[][] = [];
): WithRank<MessageWithContentFragmentsType>[][] => {
const groupedMessages: WithRank<MessageWithContentFragmentsType>[][] = [];
let tempContentFragments: ContentFragmentType[] = [];

messages
Expand All @@ -387,7 +388,7 @@ const groupMessagesByType = (
if (isContentFragmentType(message)) {
tempContentFragments.push(message); // Collect content fragments.
} else {
let messageWithContentFragments: MessageWithContentFragmentsType;
let messageWithContentFragments: WithRank<MessageWithContentFragmentsType>;
if (isUserMessageType(message)) {
// Attach collected content fragments to the user message.
messageWithContentFragments = {
Expand Down
3 changes: 2 additions & 1 deletion front/components/assistant/conversation/MessageGroup.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
FetchConversationMessagesResponse,
MessageWithContentFragmentsType,
UserType,
WithRank,
WorkspaceType,
} from "@dust-tt/types";
import React, { useEffect, useRef } from "react";
Expand All @@ -10,7 +11,7 @@ import MessageItem from "@app/components/assistant/conversation/MessageItem";
import type { AgentMessageFeedbackType } from "@app/lib/api/assistant/feedback";

interface MessageGroupProps {
messages: MessageWithContentFragmentsType[];
messages: WithRank<MessageWithContentFragmentsType>[];
isLastMessageGroup: boolean;
conversationId: string;
feedbacks: AgentMessageFeedbackType[];
Expand Down
Loading
Loading