@lobehub/chat 1.96.3 → 1.96.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.
@@ -0,0 +1,84 @@
1
+ ---
2
+ description: 包含添加 debug 日志请求时
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+ # Debug 包使用指南
7
+
8
+ 本项目使用 [debug](mdc:https:/github.com/debug-js/debug) 包进行调试日志记录。使用此规则来确保团队成员统一调试日志格式。
9
+
10
+ ## 基本用法
11
+
12
+ 1. 导入 debug 包:
13
+
14
+ ```typescript
15
+ import debug from 'debug';
16
+ ```
17
+
18
+ 2. 创建一个命名空间的日志记录器:
19
+
20
+ ```typescript
21
+ // 格式: lobe:[模块]:[子模块]
22
+ const log = debug('lobe-[模块名]:[子模块名]');
23
+ ```
24
+
25
+ 3. 使用日志记录器:
26
+
27
+ ```typescript
28
+ log('简单消息');
29
+ log('带变量的消息: %O', object);
30
+ log('格式化数字: %d', number);
31
+ ```
32
+
33
+ ## 命名空间约定
34
+
35
+ - 桌面应用相关: `lobe-desktop:[模块]`
36
+ - 服务端相关: `lobe-server:[模块]`
37
+ - 客户端相关: `lobe-client:[模块]`
38
+ - 路由相关: `lobe-[类型]-router:[模块]`
39
+
40
+ ## 格式说明符
41
+
42
+ - `%O` - 对象展开(推荐用于复杂对象)
43
+ - `%o` - 对象
44
+ - `%s` - 字符串
45
+ - `%d` - 数字
46
+
47
+ ## 示例
48
+
49
+ 查看 [market/index.ts](mdc:src/server/routers/edge/market/index.ts) 中的使用示例:
50
+
51
+ ```typescript
52
+ import debug from 'debug';
53
+
54
+ const log = debug('lobe-edge-router:market');
55
+
56
+ log('getAgent input: %O', input);
57
+ ```
58
+
59
+ ## 启用调试
60
+
61
+ 要在开发时启用调试输出,需设置环境变量:
62
+
63
+ ### 在浏览器中
64
+
65
+ 在控制台执行:
66
+ ```javascript
67
+ localStorage.debug = 'lobe-*'
68
+ ```
69
+
70
+ ### 在 Node.js 环境中
71
+
72
+ ```bash
73
+ DEBUG=lobe-* npm run dev
74
+ # 或者
75
+ DEBUG=lobe-* pnpm dev
76
+ ```
77
+
78
+ ### 在 Electron 应用中
79
+
80
+ 可以在主进程和渲染进程启动前设置环境变量:
81
+
82
+ ```typescript
83
+ process.env.DEBUG = 'lobe-*';
84
+ ```
@@ -0,0 +1,188 @@
1
+ ---
2
+ description: 桌面端测试
3
+ globs:
4
+ alwaysApply: false
5
+ ---
6
+ # 桌面端控制器单元测试指南
7
+
8
+ ## 测试框架与目录结构
9
+
10
+ LobeChat 桌面端使用 Vitest 作为测试框架。控制器的单元测试应放置在对应控制器文件同级的 `__tests__` 目录下,并以原控制器文件名加 `.test.ts` 作为文件名。
11
+
12
+ ```
13
+ apps/desktop/src/main/controllers/
14
+ ├── __tests__/
15
+ │ ├── index.test.ts
16
+ │ ├── MenuCtr.test.ts
17
+ │ └── ...
18
+ ├── McpCtr.ts
19
+ ├── MenuCtr.ts
20
+ └── ...
21
+ ```
22
+
23
+ ## 测试文件基本结构
24
+
25
+ ```typescript
26
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
27
+
28
+ import type { App } from '@/core/App';
29
+
30
+ import YourController from '../YourControllerName';
31
+
32
+ // 模拟依赖
33
+ vi.mock('依赖模块', () => ({
34
+ 依赖函数: vi.fn(),
35
+ }));
36
+
37
+ // 模拟 App 实例
38
+ const mockApp = {
39
+ // 按需模拟必要的 App 属性和方法
40
+ } as unknown as App;
41
+
42
+ describe('YourController', () => {
43
+ let controller: YourController;
44
+
45
+ beforeEach(() => {
46
+ vi.clearAllMocks();
47
+ controller = new YourController(mockApp);
48
+ });
49
+
50
+ describe('方法名', () => {
51
+ it('测试场景描述', async () => {
52
+ // 准备测试数据
53
+
54
+ // 执行被测方法
55
+ const result = await controller.方法名(参数);
56
+
57
+ // 验证结果
58
+ expect(result).toMatchObject(预期结果);
59
+ });
60
+ });
61
+ });
62
+ ```
63
+
64
+ ## 模拟外部依赖
65
+
66
+ ### 模拟模块函数
67
+
68
+ ```typescript
69
+ const mockFunction = vi.fn();
70
+
71
+ vi.mock('module-name', () => ({
72
+ functionName: mockFunction,
73
+ }));
74
+ ```
75
+
76
+ ### 模拟 Node.js 核心模块
77
+
78
+ 例如模拟 `child_process.exec` 和 `util.promisify`:
79
+
80
+ ```typescript
81
+ // 存储模拟的 exec 实现
82
+ const mockExecImpl = vi.fn();
83
+
84
+ // 模拟 child_process.exec
85
+ vi.mock('child_process', () => ({
86
+ exec: vi.fn((cmd, callback) => {
87
+ return mockExecImpl(cmd, callback);
88
+ }),
89
+ }));
90
+
91
+ // 模拟 util.promisify
92
+ vi.mock('util', () => ({
93
+ promisify: vi.fn((fn) => {
94
+ return async (cmd: string) => {
95
+ return new Promise((resolve, reject) => {
96
+ mockExecImpl(cmd, (error: Error | null, result: any) => {
97
+ if (error) reject(error);
98
+ else resolve(result);
99
+ });
100
+ });
101
+ };
102
+ }),
103
+ }));
104
+ ```
105
+
106
+ ## 编写有效的测试用例
107
+
108
+ ### 测试分类
109
+
110
+ 将测试用例分为不同类别,每个类别测试一个特定场景:
111
+
112
+ ```typescript
113
+ // 成功场景
114
+ it('应该成功完成操作', async () => {});
115
+
116
+ // 边界条件
117
+ it('应该处理边界情况', async () => {});
118
+
119
+ // 错误处理
120
+ it('应该优雅地处理错误', async () => {});
121
+ ```
122
+
123
+ ### 设置测试数据
124
+
125
+ ```typescript
126
+ // 模拟返回值
127
+ mockExecImpl.mockImplementation((cmd: string, callback: any) => {
128
+ if (cmd === '命令') {
129
+ callback(null, { stdout: '成功输出' });
130
+ } else {
131
+ callback(new Error('错误信息'), null);
132
+ }
133
+ });
134
+ ```
135
+
136
+ ### 断言
137
+
138
+ 使用 Vitest 的断言函数验证结果:
139
+
140
+ ```typescript
141
+ // 检查基本值
142
+ expect(result.success).toBe(true);
143
+
144
+ // 检查对象部分匹配
145
+ expect(result.data).toMatchObject({
146
+ key: 'value',
147
+ });
148
+
149
+ // 检查数组
150
+ expect(result.items).toHaveLength(2);
151
+ expect(result.items[0].name).toBe('expectedName');
152
+
153
+ // 检查函数调用
154
+ expect(mockFunction).toHaveBeenCalledWith(expectedArgs);
155
+ expect(mockFunction).toHaveBeenCalledTimes(1);
156
+ ```
157
+
158
+ ## 最佳实践
159
+
160
+ 1. **隔离测试**:确保每个测试互不影响,使用 `beforeEach` 重置模拟和状态
161
+ 2. **全面覆盖**:测试正常流程、边界条件和错误处理
162
+ 3. **清晰命名**:测试名称应清晰描述测试内容和预期结果
163
+ 4. **避免测试实现细节**:测试应该关注行为而非实现细节,使代码重构不会破坏测试
164
+ 5. **模拟外部依赖**:使用 `vi.mock()` 模拟所有外部依赖,减少测试的不确定性
165
+
166
+ ## 示例:测试 IPC 事件处理方法
167
+
168
+ ```typescript
169
+ it('应该正确处理 IPC 事件', async () => {
170
+ // 模拟依赖
171
+ mockSomething.mockReturnValue({ result: 'success' });
172
+
173
+ // 调用 IPC 方法
174
+ const result = await controller.ipcMethodName({
175
+ param1: 'value1',
176
+ param2: 'value2',
177
+ });
178
+
179
+ // 验证结果
180
+ expect(result).toEqual({
181
+ success: true,
182
+ data: { result: 'success' },
183
+ });
184
+
185
+ // 验证依赖调用
186
+ expect(mockSomething).toHaveBeenCalledWith('value1', 'value2');
187
+ });
188
+ ```
@@ -1,5 +1,5 @@
1
1
  ---
2
- description:
2
+ description: 当要做 electron 相关工作时
3
3
  globs:
4
4
  alwaysApply: false
5
5
  ---
package/CHANGELOG.md CHANGED
@@ -2,6 +2,23 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ### [Version 1.96.4](https://github.com/lobehub/lobe-chat/compare/v1.96.3...v1.96.4)
6
+
7
+ <sup>Released on **2025-06-22**</sup>
8
+
9
+ <br/>
10
+
11
+ <details>
12
+ <summary><kbd>Improvements and Fixes</kbd></summary>
13
+
14
+ </details>
15
+
16
+ <div align="right">
17
+
18
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
19
+
20
+ </div>
21
+
5
22
  ### [Version 1.96.3](https://github.com/lobehub/lobe-chat/compare/v1.96.2...v1.96.3)
6
23
 
7
24
  <sup>Released on **2025-06-22**</sup>
package/README.md CHANGED
@@ -39,12 +39,7 @@ One-click **FREE** deployment of your private OpenAI ChatGPT/Claude/Gemini/Groq/
39
39
 
40
40
  <sup>Pioneering the new age of thinking and creating. Built for you, the Super Individual.</sup>
41
41
 
42
- [![][github-trending-shield]][github-trending-url]
43
- <br />
44
- <br />
45
- <a href="https://vercel.com/oss">
46
- <img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" />
47
- </a>
42
+ [![][github-trending-shield]][github-trending-url] <br /> <br /> <a href="https://vercel.com/oss"> <img alt="Vercel OSS Program" src="https://vercel.com/oss/program-badge.svg" /> </a>
48
43
 
49
44
  ![][image-overview]
50
45
 
package/changelog/v1.json CHANGED
@@ -1,4 +1,9 @@
1
1
  [
2
+ {
3
+ "children": {},
4
+ "date": "2025-06-22",
5
+ "version": "1.96.4"
6
+ },
2
7
  {
3
8
  "children": {},
4
9
  "date": "2025-06-22",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.96.3",
3
+ "version": "1.96.4",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -121,7 +121,6 @@ export const DEFAULT_MODEL_PROVIDER_LIST = [
121
121
  GoogleProvider,
122
122
  VertexAIProvider,
123
123
  DeepSeekProvider,
124
- PPIOProvider,
125
124
  HuggingFaceProvider,
126
125
  OpenRouterProvider,
127
126
  CloudflareProvider,
@@ -1,5 +1,5 @@
1
- import { Alert, Button } from '@lobehub/ui';
2
- import { App, Card, Typography } from 'antd';
1
+ import { Alert, Button, Text } from '@lobehub/ui';
2
+ import { App, Card } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { AlertCircle } from 'lucide-react';
5
5
  import { useTranslation } from 'react-i18next';
@@ -7,8 +7,6 @@ import { Flexbox } from 'react-layout-kit';
7
7
 
8
8
  import { resetClientDatabase } from '@/database/client/db';
9
9
 
10
- const { Text, Paragraph } = Typography;
11
-
12
10
  const useStyles = createStyles(({ css, token }) => ({
13
11
  card: css`
14
12
  border-radius: ${token.borderRadiusLG}px;
@@ -27,7 +25,7 @@ const Backup = () => {
27
25
  extra={<Text type="secondary">{t('clientDB.solve.backup.desc')}</Text>}
28
26
  title={t('clientDB.solve.backup.title')}
29
27
  >
30
- <Paragraph>{t('clientDB.solve.backup.exportDesc')}</Paragraph>
28
+ <Text as={'p'}>{t('clientDB.solve.backup.exportDesc')}</Text>
31
29
  <Button block type={'primary'}>
32
30
  {t('clientDB.solve.backup.export')}
33
31
  </Button>
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
 
3
- import { Alert, Button, CodeEditor, Icon } from '@lobehub/ui';
4
- import { Card, List, Typography } from 'antd';
3
+ import { Alert, Button, CodeEditor, Icon, Text } from '@lobehub/ui';
4
+ import { Card, List } from 'antd';
5
5
  import { createStyles } from 'antd-style';
6
6
  import dayjs from 'dayjs';
7
7
  import isEqual from 'fast-deep-equal';
@@ -14,8 +14,6 @@ import { clientDB, updateMigrationRecord } from '@/database/client/db';
14
14
  import { useGlobalStore } from '@/store/global';
15
15
  import { clientDBSelectors } from '@/store/global/selectors';
16
16
 
17
- const { Text } = Typography;
18
-
19
17
  // 使用 antd-style 创建样式
20
18
  const useStyles = createStyles(({ css, token }) => ({
21
19
  actionBar: css`
@@ -1,4 +1,4 @@
1
- import { Typography } from 'antd';
1
+ import { Text } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
@@ -8,8 +8,6 @@ import { KnowledgeItem } from '@/types/knowledgeBase';
8
8
 
9
9
  import Actions from './Action';
10
10
 
11
- const { Paragraph } = Typography;
12
-
13
11
  const useStyles = createStyles(({ css, token }) => ({
14
12
  desc: css`
15
13
  margin: 0 !important;
@@ -51,14 +49,14 @@ const PluginItem = memo<KnowledgeItem>(({ id, fileType, name, type, description,
51
49
  <KnowledgeIcon fileType={fileType} name={name} size={{ file: 40, repo: 40 }} type={type} />
52
50
  <Flexbox flex={1} gap={4} style={{ overflow: 'hidden', position: 'relative' }}>
53
51
  <Flexbox align={'center'} gap={8} horizontal>
54
- <Paragraph className={styles.title} ellipsis={{ rows: 1 }}>
52
+ <Text className={styles.title} ellipsis>
55
53
  {name}
56
- </Paragraph>
54
+ </Text>
57
55
  </Flexbox>
58
56
  {description && (
59
- <Paragraph className={styles.desc} ellipsis={{ rows: 1 }}>
57
+ <Text className={styles.desc} ellipsis>
60
58
  {description}
61
- </Paragraph>
59
+ </Text>
62
60
  )}
63
61
  </Flexbox>
64
62
  </Flexbox>
@@ -1,5 +1,5 @@
1
- import { ActionIcon, Icon, Segmented } from '@lobehub/ui';
2
- import { ConfigProvider, Typography } from 'antd';
1
+ import { ActionIcon, Icon, Segmented, Text } from '@lobehub/ui';
2
+ import { ConfigProvider } from 'antd';
3
3
  import { cx } from 'antd-style';
4
4
  import { ArrowLeft, CodeIcon, EyeIcon } from 'lucide-react';
5
5
  import { useTranslation } from 'react-i18next';
@@ -34,9 +34,9 @@ const Header = () => {
34
34
  <Flexbox align={'center'} flex={1} gap={12} horizontal justify={'space-between'} width={'100%'}>
35
35
  <Flexbox align={'center'} gap={4} horizontal>
36
36
  <ActionIcon icon={ArrowLeft} onClick={() => closeArtifact()} size={'small'} />
37
- <Typography.Text className={cx(oneLineEllipsis)} type={'secondary'}>
37
+ <Text className={cx(oneLineEllipsis)} type={'secondary'}>
38
38
  {artifactTitle}
39
- </Typography.Text>
39
+ </Text>
40
40
  </Flexbox>
41
41
  <ConfigProvider
42
42
  theme={{
@@ -1,5 +1,5 @@
1
- import { ActionIcon } from '@lobehub/ui';
2
- import { Skeleton, Typography } from 'antd';
1
+ import { ActionIcon, Text } from '@lobehub/ui';
2
+ import { Skeleton } from 'antd';
3
3
  import { ArrowLeft } from 'lucide-react';
4
4
  import { Flexbox } from 'react-layout-kit';
5
5
 
@@ -25,9 +25,9 @@ const Header = () => {
25
25
  {isLoading ? (
26
26
  <Skeleton.Button active style={{ height: 28 }} />
27
27
  ) : (
28
- <Typography.Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
28
+ <Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
29
29
  {data?.name}
30
- </Typography.Text>
30
+ </Text>
31
31
  )}
32
32
  </Flexbox>
33
33
  );
@@ -1,4 +1,4 @@
1
- import { Typography } from 'antd';
1
+ import { Text } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import { memo } from 'react';
4
4
  import { Flexbox } from 'react-layout-kit';
@@ -43,8 +43,8 @@ const FileItem = memo<ChatFileItem>(({ name, fileType, size, id }) => {
43
43
  >
44
44
  <FileIcon fileName={name} fileType={fileType} />
45
45
  <Flexbox>
46
- <Typography.Text ellipsis={{ tooltip: true }}>{name}</Typography.Text>
47
- <Typography.Text type={'secondary'}>{formatSize(size)}</Typography.Text>
46
+ <Text ellipsis={{ tooltip: true }}>{name}</Text>
47
+ <Text type={'secondary'}>{formatSize(size)}</Text>
48
48
  </Flexbox>
49
49
  </Flexbox>
50
50
  );
@@ -1,5 +1,4 @@
1
- import { Avatar, Icon } from '@lobehub/ui';
2
- import { Typography } from 'antd';
1
+ import { Avatar, Icon, Text } from '@lobehub/ui';
3
2
  import { useTheme } from 'antd-style';
4
3
  import isEqual from 'fast-deep-equal';
5
4
  import { InboxIcon } from 'lucide-react';
@@ -35,7 +34,7 @@ const FileList = () => {
35
34
  size={48}
36
35
  />
37
36
  <Balancer>
38
- <Typography.Text type={'secondary'}>{t('emptyKnowledgeList')}</Typography.Text>
37
+ <Text type={'secondary'}>{t('emptyKnowledgeList')}</Text>
39
38
  </Balancer>
40
39
  </Center>
41
40
  ) : (
@@ -1,4 +1,4 @@
1
- import { Typography } from 'antd';
1
+ import { Text } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { Flexbox } from 'react-layout-kit';
@@ -10,9 +10,9 @@ export const Files = memo(() => {
10
10
 
11
11
  return (
12
12
  <Flexbox gap={8}>
13
- <Typography.Title level={5} style={{ marginInline: 12 }}>
13
+ <Text as={'h5'} style={{ marginInline: 12 }}>
14
14
  {t('files')}
15
- </Typography.Title>
15
+ </Text>
16
16
  <FileList />
17
17
  </Flexbox>
18
18
  );
@@ -1,5 +1,4 @@
1
- import { Icon, Tag } from '@lobehub/ui';
2
- import { Typography } from 'antd';
1
+ import { Icon, Tag, Text } from '@lobehub/ui';
3
2
  import isEqual from 'fast-deep-equal';
4
3
  import { CircuitBoard } from 'lucide-react';
5
4
  import { memo } from 'react';
@@ -53,9 +52,9 @@ const ArtifactItem = memo<ArtifactItemProps>(({ payload, messageId, identifier =
53
52
  <Tag>{payload?.apiName}</Tag>
54
53
  </Flexbox>
55
54
  <div>
56
- <Typography.Text ellipsis style={{ fontSize: 12 }} type={'secondary'}>
55
+ <Text ellipsis style={{ fontSize: 12 }} type={'secondary'}>
57
56
  {args}
58
- </Typography.Text>
57
+ </Text>
59
58
  </div>
60
59
  </Flexbox>
61
60
  </Flexbox>
@@ -1,5 +1,5 @@
1
- import { Avatar, Icon } from '@lobehub/ui';
2
- import { Skeleton, Typography } from 'antd';
1
+ import { Avatar, Icon, Text } from '@lobehub/ui';
2
+ import { Skeleton } from 'antd';
3
3
  import { useTheme } from 'antd-style';
4
4
  import isEqual from 'fast-deep-equal';
5
5
  import { Origami } from 'lucide-react';
@@ -41,7 +41,7 @@ const ArtifactList = () => {
41
41
  size={48}
42
42
  />
43
43
  <Balancer>
44
- <Typography.Text type={'secondary'}>{t('emptyArtifactList')}</Typography.Text>
44
+ <Text type={'secondary'}>{t('emptyArtifactList')}</Text>
45
45
  </Balancer>
46
46
  </Center>
47
47
  ) : (
@@ -1,4 +1,4 @@
1
- import { Typography } from 'antd';
1
+ import { Text } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
  import { Flexbox } from 'react-layout-kit';
@@ -10,9 +10,9 @@ export const Artifacts = memo(() => {
10
10
 
11
11
  return (
12
12
  <Flexbox gap={8}>
13
- <Typography.Title level={5} style={{ marginInline: 12 }}>
13
+ <Text as={'h5'} style={{ marginInline: 12 }}>
14
14
  {t('Plugins')}
15
- </Typography.Title>
15
+ </Text>
16
16
  <ArtifactList />
17
17
  </Flexbox>
18
18
  );
@@ -1,6 +1,6 @@
1
1
  'use client';
2
2
 
3
- import { Typography } from 'antd';
3
+ import { Text } from '@lobehub/ui';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
@@ -8,9 +8,9 @@ const Title = memo(() => {
8
8
  const { t } = useTranslation('portal');
9
9
 
10
10
  return (
11
- <Typography.Text style={{ fontSize: 16 }} type={'secondary'}>
11
+ <Text style={{ fontSize: 16 }} type={'secondary'}>
12
12
  {t('title')}
13
- </Typography.Text>
13
+ </Text>
14
14
  );
15
15
  });
16
16
 
@@ -1,4 +1,4 @@
1
- import { Typography } from 'antd';
1
+ import { Text } from '@lobehub/ui';
2
2
  import { useTranslation } from 'react-i18next';
3
3
  import { Flexbox } from 'react-layout-kit';
4
4
 
@@ -9,9 +9,9 @@ const Header = () => {
9
9
 
10
10
  return (
11
11
  <Flexbox align={'center'} gap={4} horizontal>
12
- <Typography.Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
12
+ <Text className={oneLineEllipsis} style={{ fontSize: 16 }} type={'secondary'}>
13
13
  {t('messageDetail')}
14
- </Typography.Text>
14
+ </Text>
15
15
  </Flexbox>
16
16
  );
17
17
  };
@@ -1,5 +1,4 @@
1
- import { ActionIcon, Icon } from '@lobehub/ui';
2
- import { Typography } from 'antd';
1
+ import { ActionIcon, Icon, Text } from '@lobehub/ui';
3
2
  import isEqual from 'fast-deep-equal';
4
3
  import { ArrowLeft, Globe } from 'lucide-react';
5
4
  import { useTranslation } from 'react-i18next';
@@ -27,9 +26,9 @@ const Header = () => {
27
26
  <Flexbox align={'center'} gap={8} horizontal>
28
27
  <ActionIcon icon={ArrowLeft} onClick={() => closeToolUI()} size={'small'} />
29
28
  <Icon icon={Globe} size={16} />
30
- <Typography.Text style={{ fontSize: 16 }} type={'secondary'}>
29
+ <Text style={{ fontSize: 16 }} type={'secondary'}>
31
30
  {t('search.title')}
32
- </Typography.Text>
31
+ </Text>
33
32
  </Flexbox>
34
33
  );
35
34
  }
@@ -37,9 +36,9 @@ const Header = () => {
37
36
  <Flexbox align={'center'} gap={4} horizontal>
38
37
  <ActionIcon icon={ArrowLeft} onClick={() => closeToolUI()} size={'small'} />
39
38
  <PluginAvatar identifier={toolUIIdentifier} size={28} />
40
- <Typography.Text style={{ fontSize: 16 }} type={'secondary'}>
39
+ <Text style={{ fontSize: 16 }} type={'secondary'}>
41
40
  {pluginTitle}
42
- </Typography.Text>
41
+ </Text>
43
42
  </Flexbox>
44
43
  );
45
44
  };
@@ -1,5 +1,4 @@
1
- import { Icon } from '@lobehub/ui';
2
- import { Typography } from 'antd';
1
+ import { Icon, Text } from '@lobehub/ui';
3
2
  import { useTheme } from 'antd-style';
4
3
  import isEqual from 'fast-deep-equal';
5
4
  import { ListTree } from 'lucide-react';
@@ -20,7 +19,7 @@ const Active = memo(() => {
20
19
  currentThread && (
21
20
  <Flexbox align={'center'} gap={8} horizontal style={{ marginInlineStart: 4 }}>
22
21
  <Icon color={theme.colorTextSecondary} icon={ListTree} size={18} />
23
- <Typography.Text
22
+ <Text
24
23
  className={oneLineEllipsis}
25
24
  ellipsis={true}
26
25
  style={{ color: theme.colorTextSecondary, fontSize: 14 }}
@@ -32,7 +31,7 @@ const Active = memo(() => {
32
31
  ) : (
33
32
  currentThread?.title
34
33
  )}
35
- </Typography.Text>
34
+ </Text>
36
35
  </Flexbox>
37
36
  )
38
37
  );
@@ -1,5 +1,5 @@
1
- import { Icon } from '@lobehub/ui';
2
- import { Switch, Typography } from 'antd';
1
+ import { Icon, Text } from '@lobehub/ui';
2
+ import { Switch } from 'antd';
3
3
  import { GitBranch } from 'lucide-react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Flexbox } from 'react-layout-kit';
@@ -17,9 +17,9 @@ const NewThreadHeader = () => {
17
17
  return (
18
18
  <Flexbox align={'center'} gap={8} horizontal style={{ marginInlineStart: 4 }}>
19
19
  <Icon icon={GitBranch} size={18} />
20
- <Typography.Text className={oneLineEllipsis} ellipsis={true} style={{ fontSize: 14 }}>
20
+ <Text className={oneLineEllipsis} ellipsis style={{ fontSize: 14 }}>
21
21
  {t('newPortalThread.title')}
22
- </Typography.Text>
22
+ </Text>
23
23
  <Flexbox align={'center'} gap={8} horizontal>
24
24
  <Switch
25
25
  checked={newThreadMode === ThreadType.Continuation}
@@ -1,5 +1,5 @@
1
- import { ActionIcon, Avatar, Icon, Tag } from '@lobehub/ui';
2
- import { Divider, Popover, Switch, Typography } from 'antd';
1
+ import { ActionIcon, Avatar, Icon, Tag, Text } from '@lobehub/ui';
2
+ import { Divider, Popover, Switch } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { TooltipPlacement } from 'antd/es/tooltip';
5
5
  import isEqual from 'fast-deep-equal';
@@ -15,8 +15,6 @@ import { pathString } from '@/utils/url';
15
15
 
16
16
  import EnableTag from './EnableTag';
17
17
 
18
- const { Text } = Typography;
19
-
20
18
  const useStyles = createStyles(({ css, token, prefixCls }) => ({
21
19
  text: css`
22
20
  max-width: 100%;
@@ -67,9 +65,7 @@ const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLe
67
65
  style={{ paddingInlineEnd: 12 }}
68
66
  >
69
67
  {t('sync.channel')}
70
- <Text className={styles.text} copyable>
71
- {channelName}
72
- </Text>
68
+ <Text className={styles.text}>{channelName}</Text>
73
69
  </Flexbox>
74
70
  </Flexbox>
75
71
  <Divider dashed style={{ margin: 0 }} />
@@ -99,9 +95,9 @@ const EnableSync = memo<EnableSyncProps>(({ hiddenActions, placement = 'bottomLe
99
95
  </Flexbox>
100
96
  )}
101
97
  </Flexbox>
102
- <Typography.Text type={'secondary'}>
98
+ <Text type={'secondary'}>
103
99
  {user.os} · {user.browser}
104
- </Typography.Text>
100
+ </Text>
105
101
  </Flexbox>
106
102
  </Flexbox>
107
103
  ))}