feat: improve copilot (#2758)
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const conversationListStyle = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'column',
|
||||
gap: '30px',
|
||||
});
|
||||
@@ -0,0 +1,22 @@
|
||||
import type { BaseChatMessage } from 'langchain/schema';
|
||||
|
||||
import { Conversation } from '../conversation';
|
||||
import { conversationListStyle } from './index.css';
|
||||
|
||||
export type ConversationListProps = {
|
||||
conversations: BaseChatMessage[];
|
||||
};
|
||||
|
||||
export const ConversationList = (props: ConversationListProps) => {
|
||||
return (
|
||||
<div className={conversationListStyle}>
|
||||
{props.conversations.map((conversation, idx) => (
|
||||
<Conversation
|
||||
type={conversation._getType()}
|
||||
text={conversation.text}
|
||||
key={idx}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -1,19 +0,0 @@
|
||||
import { marked } from 'marked';
|
||||
import { type ReactElement, useMemo } from 'react';
|
||||
|
||||
export interface ConversationProps {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export const Conversation = (props: ConversationProps): ReactElement => {
|
||||
const html = useMemo(() => marked.parse(props.text), [props.text]);
|
||||
return (
|
||||
<div>
|
||||
<div
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: html,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,15 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const conversationStyle = style({
|
||||
padding: '10px 18px',
|
||||
});
|
||||
|
||||
export const aiMessageStyle = style({
|
||||
backgroundColor: 'rgba(207, 252, 255, 0.3)',
|
||||
borderRadius: '18px 18px 18px 2px',
|
||||
});
|
||||
|
||||
export const humanMessageStyle = style({
|
||||
borderRadius: '18px 18px 2px 18px',
|
||||
backgroundColor: 'white',
|
||||
});
|
||||
42
plugins/copilot/src/core/components/conversation/index.tsx
Normal file
42
plugins/copilot/src/core/components/conversation/index.tsx
Normal file
@@ -0,0 +1,42 @@
|
||||
import { clsx } from 'clsx';
|
||||
import type { MessageType } from 'langchain/schema';
|
||||
import { marked } from 'marked';
|
||||
import { gfmHeadingId } from 'marked-gfm-heading-id';
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-expect-error
|
||||
import { mangle } from 'marked-mangle';
|
||||
import { type ReactElement, useMemo } from 'react';
|
||||
|
||||
import {
|
||||
aiMessageStyle,
|
||||
conversationStyle,
|
||||
humanMessageStyle,
|
||||
} from './index.css';
|
||||
|
||||
marked.use(
|
||||
gfmHeadingId({
|
||||
prefix: 'affine-',
|
||||
})
|
||||
);
|
||||
|
||||
marked.use(mangle());
|
||||
|
||||
export interface ConversationProps {
|
||||
type: MessageType;
|
||||
text: string;
|
||||
}
|
||||
|
||||
export const Conversation = (props: ConversationProps): ReactElement => {
|
||||
const html = useMemo(() => marked.parse(props.text), [props.text]);
|
||||
return (
|
||||
<div
|
||||
className={clsx(conversationStyle, {
|
||||
[aiMessageStyle]: props.type === 'ai',
|
||||
[humanMessageStyle]: props.type === 'human',
|
||||
})}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: html,
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
};
|
||||
@@ -0,0 +1,17 @@
|
||||
import { style } from '@vanilla-extract/css';
|
||||
|
||||
export const followingUpStyle = style({
|
||||
display: 'flex',
|
||||
flexDirection: 'row',
|
||||
flexWrap: 'wrap',
|
||||
gap: '10px',
|
||||
alignItems: 'flex-start',
|
||||
});
|
||||
|
||||
export const questionStyle = style({
|
||||
backgroundColor: 'white',
|
||||
borderRadius: '8px',
|
||||
color: '#8E8D91',
|
||||
padding: '2px 10px',
|
||||
cursor: 'pointer',
|
||||
});
|
||||
19
plugins/copilot/src/core/components/following-up/index.tsx
Normal file
19
plugins/copilot/src/core/components/following-up/index.tsx
Normal file
@@ -0,0 +1,19 @@
|
||||
import type { ReactElement } from 'react';
|
||||
|
||||
import { followingUpStyle, questionStyle } from './index.css';
|
||||
|
||||
export type FollowingUpProps = {
|
||||
questions: string[];
|
||||
};
|
||||
|
||||
export const FollowingUp = (props: FollowingUpProps): ReactElement => {
|
||||
return (
|
||||
<div className={followingUpStyle}>
|
||||
{props.questions.map((question, index) => (
|
||||
<div className={questionStyle} key={index}>
|
||||
{question}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Reference in New Issue
Block a user