@lobehub/chat 1.135.2 → 1.135.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.i18nrc.js +1 -1
- package/CHANGELOG.md +58 -0
- package/changelog/v1.json +18 -0
- package/docs/usage/features/auth.mdx +0 -5
- package/docs/usage/features/auth.zh-CN.mdx +0 -5
- package/locales/ko-KR/auth.json +35 -35
- package/locales/ko-KR/changelog.json +7 -7
- package/locales/ko-KR/chat.json +94 -94
- package/locales/ko-KR/clerk.json +74 -74
- package/locales/ko-KR/color.json +10 -10
- package/locales/ko-KR/common.json +114 -114
- package/locales/ko-KR/components.json +75 -75
- package/locales/ko-KR/discover.json +118 -118
- package/locales/ko-KR/editor.json +10 -10
- package/locales/ko-KR/file.json +25 -25
- package/locales/ko-KR/hotkey.json +21 -21
- package/locales/ko-KR/image.json +19 -19
- package/locales/ko-KR/knowledgeBase.json +3 -3
- package/locales/ko-KR/market.json +14 -14
- package/locales/ko-KR/metadata.json +19 -19
- package/locales/ko-KR/migration.json +15 -15
- package/locales/ko-KR/modelProvider.json +119 -119
- package/locales/ko-KR/oauth.json +19 -19
- package/locales/ko-KR/plugin.json +106 -106
- package/locales/ko-KR/portal.json +5 -5
- package/locales/ko-KR/providers.json +60 -60
- package/locales/ko-KR/ragEval.json +10 -10
- package/locales/ko-KR/setting.json +67 -67
- package/locales/ko-KR/subscription.json +4 -4
- package/locales/ko-KR/thread.json +3 -3
- package/locales/ko-KR/tool.json +25 -25
- package/locales/ko-KR/welcome.json +24 -24
- package/package.json +2 -2
- package/packages/const/src/index.ts +1 -0
- package/packages/const/src/settings/index.ts +1 -0
- package/packages/model-bank/src/aiModels/aihubmix.ts +25 -0
- package/packages/model-bank/src/aiModels/nvidia.ts +17 -1
- package/packages/model-bank/src/aiModels/openai.ts +80 -1
- package/packages/model-runtime/src/const/models.ts +2 -0
- package/packages/model-runtime/src/providers/openai/index.ts +15 -11
- package/packages/model-runtime/src/providers/openrouter/index.ts +7 -2
- package/packages/model-runtime/src/providers/openrouter/type.ts +4 -2
- package/packages/model-runtime/src/providers/vercelaigateway/index.ts +7 -0
- package/packages/model-runtime/src/utils/modelParse.ts +31 -3
- package/packages/prompts/promptfoo/summary-title/eval.yaml +9 -0
- package/packages/types/src/aiProvider.ts +1 -2
- package/packages/types/src/discover/models.ts +3 -2
- package/packages/types/src/discover/providers.ts +3 -2
- package/packages/types/src/message/chat.ts +13 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/ChatItem/index.tsx +1 -5
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +1 -1
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/CreateNewModelModal/Form.tsx +1 -2
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/ModelItem.tsx +1 -4
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/ListItem.tsx +1 -2
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/SortModelModal/index.tsx +1 -1
- package/src/{components → features}/ChatItem/ChatItem.tsx +5 -35
- package/src/{components → features}/ChatItem/components/MessageContent.tsx +27 -7
- package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/index.tsx +1 -1
- package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.test.ts +1 -1
- package/src/features/Conversation/{Actions → Messages/Assistant/Actions}/Error.tsx +1 -1
- package/src/features/Conversation/{components/ChatItem/ActionsBar.tsx → Messages/Assistant/Actions/index.tsx} +71 -44
- package/src/features/Conversation/Messages/Assistant/Block.tsx +63 -0
- package/src/features/Conversation/{Extras/Assistant.test.tsx → Messages/Assistant/Extra/index.test.tsx} +36 -31
- package/src/features/Conversation/{Extras/Assistant.tsx → Messages/Assistant/Extra/index.tsx} +13 -7
- package/src/features/Conversation/Messages/Assistant/MessageContent.tsx +102 -0
- package/src/features/Conversation/Messages/Assistant/index.tsx +235 -84
- package/src/features/Conversation/Messages/User/Actions.tsx +153 -0
- package/src/features/Conversation/Messages/User/BelowMessage.tsx +7 -2
- package/src/features/Conversation/{Extras/User.tsx → Messages/User/Extra.tsx} +9 -7
- package/src/features/Conversation/Messages/User/MessageContent.tsx +31 -0
- package/src/features/Conversation/Messages/User/index.tsx +127 -24
- package/src/features/Conversation/Messages/index.tsx +152 -0
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/ModelCard.tsx +4 -3
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/pricing.ts +3 -2
- package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.test.ts +2 -3
- package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/Preview.tsx +1 -1
- package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/index.tsx +1 -1
- package/src/features/Conversation/components/VirtualizedList/index.tsx +1 -0
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +29 -1
- package/src/features/Conversation/hooks/useDoubleClickEdit.ts +42 -0
- package/src/features/Conversation/index.ts +1 -1
- package/src/features/Conversation/types/{index.tsx → index.ts} +0 -7
- package/src/features/Portal/Thread/Chat/ChatItem.tsx +0 -7
- package/src/hooks/useUserAvatar.test.ts +129 -0
- package/src/hooks/useUserAvatar.ts +19 -0
- package/src/server/routers/lambda/aiModel.ts +7 -8
- package/src/store/user/slices/settings/selectors/settings.ts +6 -5
- package/src/features/ChatItem/index.tsx +0 -58
- package/src/features/Conversation/Actions/Assistant.tsx +0 -68
- package/src/features/Conversation/Actions/Fallback.tsx +0 -19
- package/src/features/Conversation/Actions/Tool.tsx +0 -33
- package/src/features/Conversation/Actions/User.tsx +0 -39
- package/src/features/Conversation/Actions/customAction.ts +0 -37
- package/src/features/Conversation/Actions/index.ts +0 -14
- package/src/features/Conversation/Extras/index.ts +0 -8
- package/src/features/Conversation/Extras/type.ts +0 -5
- package/src/features/Conversation/Messages/index.ts +0 -45
- package/src/features/Conversation/components/ChatItem/index.tsx +0 -358
- /package/src/{components → features}/ChatItem/components/Actions.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Avatar.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/BorderSpacing.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/ErrorContent.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Loading.tsx +0 -0
- /package/src/{components → features}/ChatItem/components/Title.tsx +0 -0
- /package/src/{components → features}/ChatItem/index.ts +0 -0
- /package/src/{components → features}/ChatItem/style.ts +0 -0
- /package/src/{components → features}/ChatItem/type.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/Render/Icon.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.test.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeArtifact/rehypePlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/Render.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LobeThinking/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/Render/index.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/LocalFile/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/Render.tsx +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/Thinking/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/index.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkCustomTagPlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/remarkPlugins/getNodeContent.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/type.ts +0 -0
- /package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/utils.ts +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/ExtraContainer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/FilePlayer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/InitPlayer.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/Player.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/TTS/index.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Translate.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/TokenProgress.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/index.tsx +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/tokens.ts +0 -0
- /package/src/features/Conversation/{Extras → components/Extras}/Usage/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/style.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareImage/type.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/Preview.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.test.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/template.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/ShareText/type.ts +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/index.tsx +0 -0
- /package/src/features/Conversation/components/{ChatItem/ShareMessageModal → ShareMessageModal}/style.ts +0 -0
- /package/src/features/Conversation/{components/ChatItem → context}/InPortalThreadContext.ts +0 -0
- /package/src/features/Conversation/{components/ChatItem/utils.test.ts → utils.test.ts} +0 -0
- /package/src/features/Conversation/{components/ChatItem/utils.ts → utils.ts} +0 -0
|
@@ -1,358 +0,0 @@
|
|
|
1
|
-
'use client';
|
|
2
|
-
|
|
3
|
-
import { createStyles } from 'antd-style';
|
|
4
|
-
import isEqual from 'fast-deep-equal';
|
|
5
|
-
import {
|
|
6
|
-
MouseEventHandler,
|
|
7
|
-
ReactNode,
|
|
8
|
-
memo,
|
|
9
|
-
use,
|
|
10
|
-
useCallback,
|
|
11
|
-
useEffect,
|
|
12
|
-
useMemo,
|
|
13
|
-
useRef,
|
|
14
|
-
} from 'react';
|
|
15
|
-
import { useTranslation } from 'react-i18next';
|
|
16
|
-
import { Flexbox } from 'react-layout-kit';
|
|
17
|
-
|
|
18
|
-
import { HtmlPreviewAction } from '@/components/HtmlPreview';
|
|
19
|
-
import { isDesktop } from '@/const/version';
|
|
20
|
-
import ChatItem from '@/features/ChatItem';
|
|
21
|
-
import {
|
|
22
|
-
VirtuosoContext,
|
|
23
|
-
removeVirtuosoVisibleItem,
|
|
24
|
-
upsertVirtuosoVisibleItem,
|
|
25
|
-
} from '@/features/Conversation/components/VirtualizedList/VirtuosoContext';
|
|
26
|
-
import { useAgentStore } from '@/store/agent';
|
|
27
|
-
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
|
28
|
-
import { useChatStore } from '@/store/chat';
|
|
29
|
-
import { chatSelectors } from '@/store/chat/selectors';
|
|
30
|
-
import { useUserStore } from '@/store/user';
|
|
31
|
-
import { userGeneralSettingsSelectors } from '@/store/user/selectors';
|
|
32
|
-
import { ChatMessage } from '@/types/message';
|
|
33
|
-
|
|
34
|
-
import ErrorMessageExtra, { useErrorContent } from '../../Error';
|
|
35
|
-
import { renderMessagesExtra } from '../../Extras';
|
|
36
|
-
import {
|
|
37
|
-
markdownCustomRenders,
|
|
38
|
-
renderBelowMessages,
|
|
39
|
-
renderMessages,
|
|
40
|
-
useAvatarsClick,
|
|
41
|
-
} from '../../Messages';
|
|
42
|
-
import History from '../History';
|
|
43
|
-
import { markdownElements } from '../MarkdownElements';
|
|
44
|
-
import { InPortalThreadContext } from './InPortalThreadContext';
|
|
45
|
-
import { normalizeThinkTags, processWithArtifact } from './utils';
|
|
46
|
-
|
|
47
|
-
const rehypePlugins = markdownElements.map((element) => element.rehypePlugin).filter(Boolean);
|
|
48
|
-
const remarkPlugins = markdownElements.map((element) => element.remarkPlugin).filter(Boolean);
|
|
49
|
-
|
|
50
|
-
const isHtmlCode = (content: string, language: string) => {
|
|
51
|
-
return (
|
|
52
|
-
language === 'html' ||
|
|
53
|
-
(language === '' && content.includes('<html>')) ||
|
|
54
|
-
(language === '' && content.includes('<!DOCTYPE html>'))
|
|
55
|
-
);
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const useStyles = createStyles(({ css, prefixCls }) => ({
|
|
59
|
-
loading: css`
|
|
60
|
-
opacity: 0.6;
|
|
61
|
-
`,
|
|
62
|
-
message: css`
|
|
63
|
-
position: relative;
|
|
64
|
-
// prevent the textarea too long
|
|
65
|
-
.${prefixCls}-input {
|
|
66
|
-
max-height: 900px;
|
|
67
|
-
}
|
|
68
|
-
`,
|
|
69
|
-
}));
|
|
70
|
-
|
|
71
|
-
export interface ChatListItemProps {
|
|
72
|
-
actionBar?: ReactNode;
|
|
73
|
-
className?: string;
|
|
74
|
-
disableEditing?: boolean;
|
|
75
|
-
enableHistoryDivider?: boolean;
|
|
76
|
-
endRender?: ReactNode;
|
|
77
|
-
id: string;
|
|
78
|
-
inPortalThread?: boolean;
|
|
79
|
-
index: number;
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
const Item = memo<ChatListItemProps>(
|
|
83
|
-
({
|
|
84
|
-
className,
|
|
85
|
-
enableHistoryDivider,
|
|
86
|
-
id,
|
|
87
|
-
actionBar,
|
|
88
|
-
endRender,
|
|
89
|
-
disableEditing,
|
|
90
|
-
inPortalThread = false,
|
|
91
|
-
index,
|
|
92
|
-
}) => {
|
|
93
|
-
const { t } = useTranslation('common');
|
|
94
|
-
const { styles, cx } = useStyles();
|
|
95
|
-
const containerRef = useRef<HTMLDivElement | null>(null);
|
|
96
|
-
|
|
97
|
-
const type = useAgentStore(agentChatConfigSelectors.displayMode);
|
|
98
|
-
const item = useChatStore(chatSelectors.getMessageById(id), isEqual);
|
|
99
|
-
const transitionMode = useUserStore(userGeneralSettingsSelectors.transitionMode);
|
|
100
|
-
|
|
101
|
-
const [
|
|
102
|
-
isMessageLoading,
|
|
103
|
-
generating,
|
|
104
|
-
isInRAGFlow,
|
|
105
|
-
editing,
|
|
106
|
-
toggleMessageEditing,
|
|
107
|
-
updateMessageContent,
|
|
108
|
-
] = useChatStore((s) => [
|
|
109
|
-
chatSelectors.isMessageLoading(id)(s),
|
|
110
|
-
chatSelectors.isMessageGenerating(id)(s),
|
|
111
|
-
chatSelectors.isMessageInRAGFlow(id)(s),
|
|
112
|
-
chatSelectors.isMessageEditing(id)(s),
|
|
113
|
-
s.toggleMessageEditing,
|
|
114
|
-
s.modifyMessageContent,
|
|
115
|
-
]);
|
|
116
|
-
|
|
117
|
-
// when the message is in RAG flow or the AI generating, it should be in loading state
|
|
118
|
-
const isProcessing = isInRAGFlow || generating;
|
|
119
|
-
const animated = transitionMode === 'fadeIn' && generating;
|
|
120
|
-
|
|
121
|
-
const onAvatarsClick = useAvatarsClick(item?.role);
|
|
122
|
-
|
|
123
|
-
const renderMessage = useCallback(
|
|
124
|
-
(editableContent: ReactNode) => {
|
|
125
|
-
if (!item?.role) return;
|
|
126
|
-
const RenderFunction = renderMessages[item.role] ?? renderMessages['default'];
|
|
127
|
-
|
|
128
|
-
if (!RenderFunction) return;
|
|
129
|
-
|
|
130
|
-
return <RenderFunction {...item} editableContent={editableContent} />;
|
|
131
|
-
},
|
|
132
|
-
[item],
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
const BelowMessage = useCallback(
|
|
136
|
-
({ data }: { data: ChatMessage }) => {
|
|
137
|
-
if (!item?.role) return;
|
|
138
|
-
const RenderFunction = renderBelowMessages[item.role] ?? renderBelowMessages['default'];
|
|
139
|
-
|
|
140
|
-
if (!RenderFunction) return;
|
|
141
|
-
|
|
142
|
-
return <RenderFunction {...data} />;
|
|
143
|
-
},
|
|
144
|
-
[item?.role],
|
|
145
|
-
);
|
|
146
|
-
|
|
147
|
-
const MessageExtra = useCallback(
|
|
148
|
-
({ data }: { data: ChatMessage }) => {
|
|
149
|
-
if (!item?.role) return;
|
|
150
|
-
let RenderFunction;
|
|
151
|
-
if (renderMessagesExtra?.[item.role]) RenderFunction = renderMessagesExtra[item.role];
|
|
152
|
-
|
|
153
|
-
if (!RenderFunction) return;
|
|
154
|
-
return <RenderFunction {...data} />;
|
|
155
|
-
},
|
|
156
|
-
[item?.role],
|
|
157
|
-
);
|
|
158
|
-
|
|
159
|
-
const markdownCustomRender = useCallback(
|
|
160
|
-
(dom: ReactNode, { text }: { text: string }) => {
|
|
161
|
-
if (!item?.role) return dom;
|
|
162
|
-
let RenderFunction;
|
|
163
|
-
|
|
164
|
-
if (renderMessagesExtra?.[item.role]) RenderFunction = markdownCustomRenders[item.role];
|
|
165
|
-
if (!RenderFunction) return dom;
|
|
166
|
-
|
|
167
|
-
return <RenderFunction displayMode={type} dom={dom} id={id} text={text} />;
|
|
168
|
-
},
|
|
169
|
-
[item?.role, type],
|
|
170
|
-
);
|
|
171
|
-
|
|
172
|
-
const error = useErrorContent(item?.error);
|
|
173
|
-
|
|
174
|
-
// remove line breaks in artifact tag to make the ast transform easier
|
|
175
|
-
const message =
|
|
176
|
-
!editing && item?.role === 'assistant'
|
|
177
|
-
? normalizeThinkTags(processWithArtifact(item?.content))
|
|
178
|
-
: item?.content;
|
|
179
|
-
|
|
180
|
-
// ======================= Performance Optimization ======================= //
|
|
181
|
-
// these useMemo/useCallback are all for the performance optimization
|
|
182
|
-
// maybe we can remove it in React 19
|
|
183
|
-
// ======================================================================== //
|
|
184
|
-
|
|
185
|
-
const components = useMemo(
|
|
186
|
-
() =>
|
|
187
|
-
Object.fromEntries(
|
|
188
|
-
markdownElements.map((element) => {
|
|
189
|
-
const Component = element.Component;
|
|
190
|
-
|
|
191
|
-
return [element.tag, (props: any) => <Component {...props} id={id} />];
|
|
192
|
-
}),
|
|
193
|
-
),
|
|
194
|
-
[id],
|
|
195
|
-
);
|
|
196
|
-
|
|
197
|
-
const markdownProps = useMemo(
|
|
198
|
-
() => ({
|
|
199
|
-
animated,
|
|
200
|
-
citations: item?.role === 'user' ? undefined : item?.search?.citations,
|
|
201
|
-
componentProps: {
|
|
202
|
-
highlight: {
|
|
203
|
-
actionsRender: ({ content, actionIconSize, language, originalNode }: any) => {
|
|
204
|
-
const showHtmlPreview = isHtmlCode(content, language);
|
|
205
|
-
|
|
206
|
-
return (
|
|
207
|
-
<>
|
|
208
|
-
{showHtmlPreview && <HtmlPreviewAction content={content} size={actionIconSize} />}
|
|
209
|
-
{originalNode}
|
|
210
|
-
</>
|
|
211
|
-
);
|
|
212
|
-
},
|
|
213
|
-
},
|
|
214
|
-
},
|
|
215
|
-
components,
|
|
216
|
-
customRender: markdownCustomRender,
|
|
217
|
-
enableCustomFootnotes: item?.role === 'assistant',
|
|
218
|
-
rehypePlugins: item?.role === 'user' ? undefined : rehypePlugins,
|
|
219
|
-
remarkPlugins: item?.role === 'user' ? undefined : remarkPlugins,
|
|
220
|
-
showFootnotes:
|
|
221
|
-
item?.role === 'user'
|
|
222
|
-
? undefined
|
|
223
|
-
: item?.search?.citations &&
|
|
224
|
-
// if the citations are all empty, we should not show the citations
|
|
225
|
-
item?.search?.citations.length > 0 &&
|
|
226
|
-
// if the citations's url and title are all the same, we should not show the citations
|
|
227
|
-
item?.search?.citations.every((item) => item.title !== item.url),
|
|
228
|
-
}),
|
|
229
|
-
[animated, components, markdownCustomRender, item?.role, item?.search],
|
|
230
|
-
);
|
|
231
|
-
|
|
232
|
-
const onChange = useCallback((value: string) => updateMessageContent(id, value), [id]);
|
|
233
|
-
const virtuosoRef = use(VirtuosoContext);
|
|
234
|
-
|
|
235
|
-
useEffect(() => {
|
|
236
|
-
if (typeof window === 'undefined' || typeof IntersectionObserver === 'undefined') return;
|
|
237
|
-
|
|
238
|
-
const element = containerRef.current;
|
|
239
|
-
if (!element) return;
|
|
240
|
-
|
|
241
|
-
const root = element.closest('[data-virtuoso-scroller]');
|
|
242
|
-
const thresholds = [0, 0.01, 0.1, 0.25, 0.5, 0.75, 0.9, 1];
|
|
243
|
-
const options: any = { threshold: thresholds };
|
|
244
|
-
|
|
245
|
-
if (root instanceof Element) options.root = root;
|
|
246
|
-
|
|
247
|
-
const observer = new IntersectionObserver((entries) => {
|
|
248
|
-
entries.forEach((entry) => {
|
|
249
|
-
if (entry.target !== element) return;
|
|
250
|
-
|
|
251
|
-
if (entry.isIntersecting) {
|
|
252
|
-
const { bottom, top } = entry.intersectionRect;
|
|
253
|
-
|
|
254
|
-
upsertVirtuosoVisibleItem(index, {
|
|
255
|
-
bottom,
|
|
256
|
-
ratio: entry.intersectionRatio,
|
|
257
|
-
top,
|
|
258
|
-
});
|
|
259
|
-
} else {
|
|
260
|
-
removeVirtuosoVisibleItem(index);
|
|
261
|
-
}
|
|
262
|
-
});
|
|
263
|
-
}, options);
|
|
264
|
-
|
|
265
|
-
observer.observe(element);
|
|
266
|
-
|
|
267
|
-
return () => {
|
|
268
|
-
observer.disconnect();
|
|
269
|
-
removeVirtuosoVisibleItem(index);
|
|
270
|
-
};
|
|
271
|
-
}, [index]);
|
|
272
|
-
|
|
273
|
-
const onDoubleClick = useCallback<MouseEventHandler<HTMLDivElement>>(
|
|
274
|
-
(e) => {
|
|
275
|
-
if (!item || disableEditing) return;
|
|
276
|
-
if (item.id === 'default' || item.error) return;
|
|
277
|
-
if (item.role && ['assistant', 'user'].includes(item.role) && e.altKey) {
|
|
278
|
-
toggleMessageEditing(id, true);
|
|
279
|
-
|
|
280
|
-
virtuosoRef?.current?.scrollIntoView({ align: 'start', behavior: 'auto', index });
|
|
281
|
-
}
|
|
282
|
-
},
|
|
283
|
-
[item, disableEditing],
|
|
284
|
-
);
|
|
285
|
-
|
|
286
|
-
const text = useMemo(
|
|
287
|
-
() => ({
|
|
288
|
-
cancel: t('cancel'),
|
|
289
|
-
confirm: t('ok'),
|
|
290
|
-
edit: t('edit'),
|
|
291
|
-
}),
|
|
292
|
-
[t],
|
|
293
|
-
);
|
|
294
|
-
|
|
295
|
-
const onEditingChange = useCallback((edit: boolean) => {
|
|
296
|
-
toggleMessageEditing(id, edit);
|
|
297
|
-
}, []);
|
|
298
|
-
|
|
299
|
-
const onContextMenu = useCallback(async () => {
|
|
300
|
-
if (isDesktop && item) {
|
|
301
|
-
const { electronSystemService } = await import('@/services/electron/system');
|
|
302
|
-
|
|
303
|
-
electronSystemService.showContextMenu('chat', {
|
|
304
|
-
content: item.content,
|
|
305
|
-
hasError: !!item.error,
|
|
306
|
-
messageId: id,
|
|
307
|
-
role: item.role,
|
|
308
|
-
});
|
|
309
|
-
}
|
|
310
|
-
}, [id, item]);
|
|
311
|
-
|
|
312
|
-
const belowMessage = useMemo(() => item && <BelowMessage data={item} />, [item]);
|
|
313
|
-
const errorMessage = useMemo(() => item && <ErrorMessageExtra data={item} />, [item]);
|
|
314
|
-
const messageExtra = useMemo(() => item && <MessageExtra data={item} />, [item]);
|
|
315
|
-
|
|
316
|
-
return (
|
|
317
|
-
item && (
|
|
318
|
-
<InPortalThreadContext.Provider value={inPortalThread}>
|
|
319
|
-
{enableHistoryDivider && <History />}
|
|
320
|
-
<Flexbox
|
|
321
|
-
className={cx(styles.message, className, isMessageLoading && styles.loading)}
|
|
322
|
-
data-index={index}
|
|
323
|
-
onContextMenu={onContextMenu}
|
|
324
|
-
ref={containerRef}
|
|
325
|
-
>
|
|
326
|
-
<ChatItem
|
|
327
|
-
actions={actionBar}
|
|
328
|
-
avatar={item.meta}
|
|
329
|
-
belowMessage={belowMessage}
|
|
330
|
-
editing={editing}
|
|
331
|
-
error={error}
|
|
332
|
-
errorMessage={errorMessage}
|
|
333
|
-
loading={isProcessing}
|
|
334
|
-
markdownProps={markdownProps}
|
|
335
|
-
message={message}
|
|
336
|
-
messageExtra={messageExtra}
|
|
337
|
-
onAvatarClick={onAvatarsClick}
|
|
338
|
-
onChange={onChange}
|
|
339
|
-
onDoubleClick={onDoubleClick}
|
|
340
|
-
onEditingChange={onEditingChange}
|
|
341
|
-
placement={type === 'chat' ? (item.role === 'user' ? 'right' : 'left') : 'left'}
|
|
342
|
-
primary={item.role === 'user'}
|
|
343
|
-
renderMessage={renderMessage}
|
|
344
|
-
text={text}
|
|
345
|
-
time={item.updatedAt || item.createdAt}
|
|
346
|
-
variant={type === 'chat' ? 'bubble' : 'docs'}
|
|
347
|
-
/>
|
|
348
|
-
{endRender}
|
|
349
|
-
</Flexbox>
|
|
350
|
-
</InPortalThreadContext.Provider>
|
|
351
|
-
)
|
|
352
|
-
);
|
|
353
|
-
},
|
|
354
|
-
);
|
|
355
|
-
|
|
356
|
-
Item.displayName = 'ChatItem';
|
|
357
|
-
|
|
358
|
-
export default Item;
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/index.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/features/Conversation/{components/MarkdownElements → MarkdownElements}/utils.ts
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
/package/src/features/Conversation/{Extras → components/Extras}/Usage/UsageDetail/TokenProgress.tsx
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|