@lobehub/lobehub 2.0.0-next.239 → 2.0.0-next.240
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/.cursor/rules/typescript.mdc +1 -0
- package/CHANGELOG.md +33 -0
- package/changelog/v1.json +5 -0
- package/locales/en-US/plugin.json +9 -0
- package/locales/zh-CN/plugin.json +9 -0
- package/package.json +1 -1
- package/packages/builtin-tool-gtd/src/client/Streaming/CreatePlan/index.tsx +4 -19
- package/packages/builtin-tool-notebook/src/client/Inspector/CreateDocument/index.tsx +51 -0
- package/packages/builtin-tool-notebook/src/client/Inspector/index.ts +14 -0
- package/packages/builtin-tool-notebook/src/client/Placeholder/CreateDocument.tsx +101 -0
- package/packages/builtin-tool-notebook/src/client/Placeholder/index.ts +10 -0
- package/packages/builtin-tool-notebook/src/client/Render/CreateDocument/DocumentCard.tsx +63 -33
- package/packages/builtin-tool-notebook/src/client/Streaming/CreateDocument/index.tsx +75 -0
- package/packages/builtin-tool-notebook/src/client/Streaming/index.ts +14 -0
- package/packages/builtin-tool-notebook/src/client/components/AnimatedNumber.tsx +57 -0
- package/packages/builtin-tool-notebook/src/client/index.ts +12 -0
- package/packages/builtin-tool-notebook/src/systemRole.ts +2 -1
- package/packages/memory-user-memory/src/extractors/base.ts +8 -13
- package/packages/memory-user-memory/src/extractors/context.test.ts +2 -7
- package/packages/memory-user-memory/src/extractors/context.ts +7 -2
- package/packages/memory-user-memory/src/extractors/experience.test.ts +2 -10
- package/packages/memory-user-memory/src/extractors/experience.ts +7 -2
- package/packages/memory-user-memory/src/extractors/gatekeeper.test.ts +2 -7
- package/packages/memory-user-memory/src/extractors/gatekeeper.ts +3 -2
- package/packages/memory-user-memory/src/extractors/identity.test.ts +2 -7
- package/packages/memory-user-memory/src/extractors/identity.ts +7 -2
- package/packages/memory-user-memory/src/extractors/preference.test.ts +2 -10
- package/packages/memory-user-memory/src/extractors/preference.ts +7 -2
- package/packages/memory-user-memory/src/prompts/gatekeeper.ts +127 -0
- package/packages/memory-user-memory/src/prompts/index.ts +2 -0
- package/packages/memory-user-memory/src/prompts/layers/context.ts +155 -0
- package/packages/memory-user-memory/src/prompts/layers/experience.ts +162 -0
- package/packages/memory-user-memory/src/prompts/layers/identity.ts +219 -0
- package/packages/memory-user-memory/src/prompts/layers/index.ts +4 -0
- package/packages/memory-user-memory/src/prompts/layers/preference.ts +164 -0
- package/packages/memory-user-memory/src/services/extractExecutor.ts +0 -7
- package/packages/memory-user-memory/src/types.ts +0 -1
- package/src/app/[variants]/(main)/image/features/GenerationFeed/index.tsx +2 -2
- package/src/app/[variants]/(main)/image/features/ImageWorkspace/Content.tsx +1 -11
- package/src/app/[variants]/(main)/image/features/PromptInput/index.tsx +1 -7
- package/src/app/[variants]/(main)/image/index.tsx +2 -5
- package/src/components/Loading/BrandTextLoading/index.module.css +0 -1
- package/src/components/StreamingMarkdown/index.tsx +88 -0
- package/src/features/Conversation/Messages/AssistantGroup/Tool/Render/index.tsx +3 -5
- package/src/features/Conversation/Messages/AssistantGroup/Tool/index.tsx +14 -0
- package/src/features/PluginDevModal/PluginPreview/EmptyState.tsx +1 -1
- package/src/locales/default/plugin.ts +9 -0
- package/src/server/routers/async/image.ts +1 -1
- package/src/server/routers/lambda/image/index.test.ts +491 -0
- package/src/server/routers/lambda/{image.ts → image/index.ts} +57 -41
- package/src/server/routers/lambda/{__tests__/image.test.ts → image/utils.test.ts} +1 -21
- package/src/server/routers/lambda/image/utils.ts +24 -0
- package/src/server/services/file/__tests__/index.test.ts +3 -3
- package/src/server/services/file/impls/index.ts +4 -4
- package/src/server/services/file/impls/s3.test.ts +57 -39
- package/src/server/services/file/impls/s3.ts +29 -21
- package/src/server/services/file/impls/type.ts +1 -2
- package/src/server/services/file/index.ts +5 -3
- package/src/tools/inspectors.ts +2 -0
- package/src/tools/placeholders.ts +5 -0
- package/src/tools/streamings.ts +2 -0
- package/packages/memory-user-memory/src/prompts/gatekeeper.md +0 -125
- package/packages/memory-user-memory/src/prompts/layers/context.md +0 -153
- package/packages/memory-user-memory/src/prompts/layers/experience.md +0 -160
- package/packages/memory-user-memory/src/prompts/layers/identity.md +0 -217
- package/packages/memory-user-memory/src/prompts/layers/preference.md +0 -162
- package/packages/memory-user-memory/src/utils/path.ts +0 -5
- package/src/server/services/file/impls/utils.test.ts +0 -154
- package/src/server/services/file/impls/utils.ts +0 -17
|
@@ -52,3 +52,4 @@ alwaysApply: false
|
|
|
52
52
|
|
|
53
53
|
- Never log user private information like api key, etc
|
|
54
54
|
- Don't use `import { log } from 'debug'` to log messages, because it will directly log the message to the console.
|
|
55
|
+
- Use console.error instead of debug package to log error message in catch block.
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,39 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
## [Version 2.0.0-next.240](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.239...v2.0.0-next.240)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2026-01-08**</sup>
|
|
8
|
+
|
|
9
|
+
#### ♻ Code Refactoring
|
|
10
|
+
|
|
11
|
+
- **memory-user-memory**: Migrated to use typescript module for prompts.
|
|
12
|
+
|
|
13
|
+
#### ✨ Features
|
|
14
|
+
|
|
15
|
+
- **notebook**: Add i18n, Inspector and Streaming components.
|
|
16
|
+
|
|
17
|
+
<br/>
|
|
18
|
+
|
|
19
|
+
<details>
|
|
20
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
21
|
+
|
|
22
|
+
#### Code refactoring
|
|
23
|
+
|
|
24
|
+
- **memory-user-memory**: Migrated to use typescript module for prompts, closes [#11344](https://github.com/lobehub/lobe-chat/issues/11344) ([902cfe5](https://github.com/lobehub/lobe-chat/commit/902cfe5))
|
|
25
|
+
|
|
26
|
+
#### What's improved
|
|
27
|
+
|
|
28
|
+
- **notebook**: Add i18n, Inspector and Streaming components, closes [#11212](https://github.com/lobehub/lobe-chat/issues/11212) ([f7dc54f](https://github.com/lobehub/lobe-chat/commit/f7dc54f))
|
|
29
|
+
|
|
30
|
+
</details>
|
|
31
|
+
|
|
32
|
+
<div align="right">
|
|
33
|
+
|
|
34
|
+
[](#readme-top)
|
|
35
|
+
|
|
36
|
+
</div>
|
|
37
|
+
|
|
5
38
|
## [Version 2.0.0-next.239](https://github.com/lobehub/lobe-chat/compare/v2.0.0-next.238...v2.0.0-next.239)
|
|
6
39
|
|
|
7
40
|
<sup>Released on **2026-01-08**</sup>
|
package/changelog/v1.json
CHANGED
|
@@ -92,6 +92,15 @@
|
|
|
92
92
|
"builtins.lobe-local-system.inspector.noResults": "No results",
|
|
93
93
|
"builtins.lobe-local-system.inspector.rename.result": "<old>{{oldName}}</old> → <new>{{newName}}</new>",
|
|
94
94
|
"builtins.lobe-local-system.title": "Local System",
|
|
95
|
+
"builtins.lobe-notebook.actions.copy": "Copy",
|
|
96
|
+
"builtins.lobe-notebook.actions.creating": "Creating document...",
|
|
97
|
+
"builtins.lobe-notebook.actions.edit": "Edit",
|
|
98
|
+
"builtins.lobe-notebook.actions.expand": "Expand",
|
|
99
|
+
"builtins.lobe-notebook.apiName.createDocument": "Create document",
|
|
100
|
+
"builtins.lobe-notebook.apiName.deleteDocument": "Delete document",
|
|
101
|
+
"builtins.lobe-notebook.apiName.getDocument": "Get document",
|
|
102
|
+
"builtins.lobe-notebook.apiName.updateDocument": "Update document",
|
|
103
|
+
"builtins.lobe-notebook.title": "Notebook",
|
|
95
104
|
"builtins.lobe-page-agent.apiName.batchUpdate": "Batch update nodes",
|
|
96
105
|
"builtins.lobe-page-agent.apiName.compareSnapshots": "Compare snapshots",
|
|
97
106
|
"builtins.lobe-page-agent.apiName.convertToList": "Convert to list",
|
|
@@ -92,6 +92,15 @@
|
|
|
92
92
|
"builtins.lobe-local-system.inspector.noResults": "无结果",
|
|
93
93
|
"builtins.lobe-local-system.inspector.rename.result": "<old>{{oldName}}</old> → <new>{{newName}}</new>",
|
|
94
94
|
"builtins.lobe-local-system.title": "本地系统",
|
|
95
|
+
"builtins.lobe-notebook.actions.copy": "复制",
|
|
96
|
+
"builtins.lobe-notebook.actions.creating": "文档创建中...",
|
|
97
|
+
"builtins.lobe-notebook.actions.edit": "编辑",
|
|
98
|
+
"builtins.lobe-notebook.actions.expand": "展开",
|
|
99
|
+
"builtins.lobe-notebook.apiName.createDocument": "创建文档",
|
|
100
|
+
"builtins.lobe-notebook.apiName.deleteDocument": "删除文档",
|
|
101
|
+
"builtins.lobe-notebook.apiName.getDocument": "获取文档",
|
|
102
|
+
"builtins.lobe-notebook.apiName.updateDocument": "更新文档",
|
|
103
|
+
"builtins.lobe-notebook.title": "笔记本",
|
|
95
104
|
"builtins.lobe-page-agent.apiName.batchUpdate": "批量更新节点",
|
|
96
105
|
"builtins.lobe-page-agent.apiName.compareSnapshots": "比较快照",
|
|
97
106
|
"builtins.lobe-page-agent.apiName.convertToList": "转换为列表",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/lobehub",
|
|
3
|
-
"version": "2.0.0-next.
|
|
3
|
+
"version": "2.0.0-next.240",
|
|
4
4
|
"description": "LobeHub - an open-source,comprehensive AI Agent 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",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import type { BuiltinStreamingProps } from '@lobechat/types';
|
|
4
|
-
import { Flexbox, Icon,
|
|
4
|
+
import { Flexbox, Icon, Text } from '@lobehub/ui';
|
|
5
5
|
import { createStaticStyles } from 'antd-style';
|
|
6
6
|
import { ListChecksIcon } from 'lucide-react';
|
|
7
7
|
import { memo } from 'react';
|
|
8
8
|
|
|
9
|
-
import
|
|
9
|
+
import StreamingMarkdown from '@/components/StreamingMarkdown';
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
import type { CreatePlanParams } from '../../../types';
|
|
12
12
|
|
|
13
13
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
14
14
|
container: css`
|
|
@@ -17,15 +17,6 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
17
17
|
border: 1px solid ${cssVar.colorBorder};
|
|
18
18
|
border-radius: 8px;
|
|
19
19
|
`,
|
|
20
|
-
content: css`
|
|
21
|
-
overflow: hidden auto;
|
|
22
|
-
|
|
23
|
-
max-height: ${MAX_CONTENT_HEIGHT}px;
|
|
24
|
-
padding: 12px;
|
|
25
|
-
border-radius: 8px;
|
|
26
|
-
|
|
27
|
-
background: ${cssVar.colorFillQuaternary};
|
|
28
|
-
`,
|
|
29
20
|
description: css`
|
|
30
21
|
font-size: 14px;
|
|
31
22
|
color: ${cssVar.colorTextSecondary};
|
|
@@ -70,13 +61,7 @@ export const CreatePlanStreaming = memo<BuiltinStreamingProps<CreatePlanParams>>
|
|
|
70
61
|
)}
|
|
71
62
|
|
|
72
63
|
{/* Context content - streaming with animation */}
|
|
73
|
-
{context
|
|
74
|
-
<div className={styles.content}>
|
|
75
|
-
<Markdown animated fontSize={13} variant={'chat'}>
|
|
76
|
-
{context}
|
|
77
|
-
</Markdown>
|
|
78
|
-
</div>
|
|
79
|
-
)}
|
|
64
|
+
<StreamingMarkdown maxHeight={100}>{context}</StreamingMarkdown>
|
|
80
65
|
</Flexbox>
|
|
81
66
|
);
|
|
82
67
|
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { BuiltinInspectorProps } from '@lobechat/types';
|
|
4
|
+
import { createStaticStyles, cx } from 'antd-style';
|
|
5
|
+
import { memo } from 'react';
|
|
6
|
+
import { useTranslation } from 'react-i18next';
|
|
7
|
+
|
|
8
|
+
import { highlightTextStyles, shinyTextStyles } from '@/styles';
|
|
9
|
+
|
|
10
|
+
import type { CreateDocumentArgs, CreateDocumentState } from '../../../types';
|
|
11
|
+
|
|
12
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
13
|
+
root: css`
|
|
14
|
+
overflow: hidden;
|
|
15
|
+
display: -webkit-box;
|
|
16
|
+
-webkit-box-orient: vertical;
|
|
17
|
+
-webkit-line-clamp: 1;
|
|
18
|
+
|
|
19
|
+
color: ${cssVar.colorTextSecondary};
|
|
20
|
+
`,
|
|
21
|
+
}));
|
|
22
|
+
|
|
23
|
+
export const CreateDocumentInspector = memo<
|
|
24
|
+
BuiltinInspectorProps<CreateDocumentArgs, CreateDocumentState>
|
|
25
|
+
>(({ args, partialArgs, isArgumentsStreaming, isLoading }) => {
|
|
26
|
+
const { t } = useTranslation('plugin');
|
|
27
|
+
|
|
28
|
+
const title = args?.title || partialArgs?.title;
|
|
29
|
+
|
|
30
|
+
// During streaming without title, show init
|
|
31
|
+
if (isArgumentsStreaming && !title) {
|
|
32
|
+
return (
|
|
33
|
+
<div className={cx(styles.root, shinyTextStyles.shinyText)}>
|
|
34
|
+
<span>{t('builtins.lobe-notebook.apiName.createDocument')}</span>
|
|
35
|
+
</div>
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
return (
|
|
40
|
+
<div
|
|
41
|
+
className={cx(styles.root, (isArgumentsStreaming || isLoading) && shinyTextStyles.shinyText)}
|
|
42
|
+
>
|
|
43
|
+
<span>{t('builtins.lobe-notebook.apiName.createDocument')}: </span>
|
|
44
|
+
{title && <span className={highlightTextStyles.primary}>{title}</span>}
|
|
45
|
+
</div>
|
|
46
|
+
);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
CreateDocumentInspector.displayName = 'CreateDocumentInspector';
|
|
50
|
+
|
|
51
|
+
export default CreateDocumentInspector;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type BuiltinInspector } from '@lobechat/types';
|
|
2
|
+
|
|
3
|
+
import { NotebookApiName } from '../../types';
|
|
4
|
+
import { CreateDocumentInspector } from './CreateDocument';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Notebook Inspector Components Registry
|
|
8
|
+
*
|
|
9
|
+
* Inspector components customize the title/header area
|
|
10
|
+
* of tool calls in the conversation UI.
|
|
11
|
+
*/
|
|
12
|
+
export const NotebookInspectors: Record<string, BuiltinInspector> = {
|
|
13
|
+
[NotebookApiName.createDocument]: CreateDocumentInspector as BuiltinInspector,
|
|
14
|
+
};
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { BuiltinPlaceholderProps } from '@lobechat/types';
|
|
4
|
+
import { Flexbox, Markdown, ScrollShadow } from '@lobehub/ui';
|
|
5
|
+
import { createStaticStyles } from 'antd-style';
|
|
6
|
+
import { NotebookText } from 'lucide-react';
|
|
7
|
+
import { memo } from 'react';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
9
|
+
|
|
10
|
+
import NeuralNetworkLoading from '@/components/NeuralNetworkLoading';
|
|
11
|
+
|
|
12
|
+
import type { CreateDocumentArgs } from '../../types';
|
|
13
|
+
|
|
14
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
15
|
+
container: css`
|
|
16
|
+
position: relative;
|
|
17
|
+
|
|
18
|
+
overflow: hidden;
|
|
19
|
+
|
|
20
|
+
width: 100%;
|
|
21
|
+
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
22
|
+
border-radius: 16px;
|
|
23
|
+
|
|
24
|
+
background: ${cssVar.colorBgElevated};
|
|
25
|
+
`,
|
|
26
|
+
content: css`
|
|
27
|
+
padding-block: 16px;
|
|
28
|
+
padding-inline: 16px;
|
|
29
|
+
`,
|
|
30
|
+
header: css`
|
|
31
|
+
padding-block: 10px;
|
|
32
|
+
padding-inline: 12px;
|
|
33
|
+
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
|
34
|
+
`,
|
|
35
|
+
icon: css`
|
|
36
|
+
color: ${cssVar.colorPrimary};
|
|
37
|
+
`,
|
|
38
|
+
statusTag: css`
|
|
39
|
+
position: absolute;
|
|
40
|
+
inset-block-end: 16px;
|
|
41
|
+
inset-inline-start: 50%;
|
|
42
|
+
transform: translateX(-50%);
|
|
43
|
+
|
|
44
|
+
display: inline-flex;
|
|
45
|
+
gap: 6px;
|
|
46
|
+
align-items: center;
|
|
47
|
+
|
|
48
|
+
padding-block: 4px;
|
|
49
|
+
padding-inline: 12px;
|
|
50
|
+
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
51
|
+
border-radius: 16px;
|
|
52
|
+
|
|
53
|
+
font-size: 14px;
|
|
54
|
+
color: ${cssVar.colorText};
|
|
55
|
+
|
|
56
|
+
background: ${cssVar.colorBgContainer};
|
|
57
|
+
`,
|
|
58
|
+
title: css`
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
display: -webkit-box;
|
|
61
|
+
-webkit-box-orient: vertical;
|
|
62
|
+
-webkit-line-clamp: 1;
|
|
63
|
+
|
|
64
|
+
font-weight: 500;
|
|
65
|
+
color: ${cssVar.colorText};
|
|
66
|
+
`,
|
|
67
|
+
}));
|
|
68
|
+
|
|
69
|
+
export const CreateDocumentPlaceholder = memo<BuiltinPlaceholderProps<CreateDocumentArgs>>(
|
|
70
|
+
({ args }) => {
|
|
71
|
+
const { t } = useTranslation('plugin');
|
|
72
|
+
const { title, content } = args || {};
|
|
73
|
+
|
|
74
|
+
return (
|
|
75
|
+
<Flexbox className={styles.container}>
|
|
76
|
+
{/* Header */}
|
|
77
|
+
<Flexbox align={'center'} className={styles.header} gap={8} horizontal>
|
|
78
|
+
<NotebookText className={styles.icon} size={16} />
|
|
79
|
+
<Flexbox flex={1}>
|
|
80
|
+
<div className={styles.title}>{title}</div>
|
|
81
|
+
</Flexbox>
|
|
82
|
+
<NeuralNetworkLoading size={20} />
|
|
83
|
+
</Flexbox>
|
|
84
|
+
{/* Content skeleton */}
|
|
85
|
+
<ScrollShadow className={styles.content} offset={12} size={12} style={{ maxHeight: 400 }}>
|
|
86
|
+
{content && (
|
|
87
|
+
<Markdown style={{ overflow: 'unset', paddingBottom: 40 }} variant={'chat'}>
|
|
88
|
+
{content}
|
|
89
|
+
</Markdown>
|
|
90
|
+
)}
|
|
91
|
+
</ScrollShadow>
|
|
92
|
+
<div className={styles.statusTag}>
|
|
93
|
+
<NeuralNetworkLoading size={14} />
|
|
94
|
+
<span style={{ fontSize: 12 }}>{t('builtins.lobe-notebook.actions.creating')}</span>
|
|
95
|
+
</div>
|
|
96
|
+
</Flexbox>
|
|
97
|
+
);
|
|
98
|
+
},
|
|
99
|
+
);
|
|
100
|
+
|
|
101
|
+
export default CreateDocumentPlaceholder;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { type BuiltinPlaceholder } from '@lobechat/types';
|
|
2
|
+
|
|
3
|
+
import { NotebookApiName } from '../../types';
|
|
4
|
+
import { CreateDocumentPlaceholder } from './CreateDocument';
|
|
5
|
+
|
|
6
|
+
export { CreateDocumentPlaceholder } from './CreateDocument';
|
|
7
|
+
|
|
8
|
+
export const NotebookPlaceholders: Record<string, BuiltinPlaceholder> = {
|
|
9
|
+
[NotebookApiName.createDocument]: CreateDocumentPlaceholder as BuiltinPlaceholder,
|
|
10
|
+
};
|
|
@@ -1,36 +1,46 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Flexbox,
|
|
3
|
+
import { ActionIcon, CopyButton, Flexbox, Markdown, ScrollShadow } from '@lobehub/ui';
|
|
4
|
+
import { Button } from 'antd';
|
|
4
5
|
import { createStaticStyles } from 'antd-style';
|
|
5
|
-
import {
|
|
6
|
+
import { Maximize2, NotebookText, PencilLine } from 'lucide-react';
|
|
6
7
|
import { memo } from 'react';
|
|
8
|
+
import { useTranslation } from 'react-i18next';
|
|
7
9
|
|
|
8
10
|
import { useChatStore } from '@/store/chat';
|
|
9
11
|
|
|
10
12
|
import { NotebookDocument } from '../../../types';
|
|
11
13
|
|
|
14
|
+
|
|
12
15
|
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
13
16
|
container: css`
|
|
14
|
-
|
|
17
|
+
position: relative;
|
|
15
18
|
|
|
16
19
|
overflow: hidden;
|
|
17
20
|
|
|
18
21
|
width: 100%;
|
|
19
|
-
padding-block: 12px;
|
|
20
|
-
padding-inline: 12px;
|
|
21
22
|
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
22
|
-
border-radius:
|
|
23
|
+
border-radius: 16px;
|
|
23
24
|
|
|
24
25
|
background: ${cssVar.colorBgElevated};
|
|
26
|
+
`,
|
|
27
|
+
content: css`
|
|
28
|
+
padding-inline: 16px;
|
|
29
|
+
|
|
30
|
+
font-size: 14px;
|
|
31
|
+
`,
|
|
32
|
+
expandButton: css`
|
|
33
|
+
position: absolute;
|
|
34
|
+
inset-block-end: 16px;
|
|
35
|
+
inset-inline-start: 50%;
|
|
36
|
+
transform: translateX(-50%);
|
|
25
37
|
|
|
26
|
-
|
|
27
|
-
background: ${cssVar.colorFillSecondary};
|
|
28
|
-
}
|
|
38
|
+
box-shadow: ${cssVar.boxShadow};
|
|
29
39
|
`,
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
40
|
+
header: css`
|
|
41
|
+
padding-block: 10px;
|
|
42
|
+
padding-inline: 12px;
|
|
43
|
+
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
|
34
44
|
`,
|
|
35
45
|
icon: css`
|
|
36
46
|
color: ${cssVar.colorPrimary};
|
|
@@ -44,9 +54,6 @@ const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
|
44
54
|
font-weight: 500;
|
|
45
55
|
color: ${cssVar.colorText};
|
|
46
56
|
`,
|
|
47
|
-
typeTag: css`
|
|
48
|
-
font-size: 11px;
|
|
49
|
-
`,
|
|
50
57
|
}));
|
|
51
58
|
|
|
52
59
|
interface DocumentCardProps {
|
|
@@ -54,30 +61,53 @@ interface DocumentCardProps {
|
|
|
54
61
|
}
|
|
55
62
|
|
|
56
63
|
const DocumentCard = memo<DocumentCardProps>(({ document }) => {
|
|
64
|
+
const { t } = useTranslation('plugin');
|
|
57
65
|
const openDocument = useChatStore((s) => s.openDocument);
|
|
58
66
|
|
|
59
|
-
const
|
|
67
|
+
const handleExpand = () => {
|
|
60
68
|
openDocument(document.id);
|
|
61
69
|
};
|
|
62
70
|
|
|
63
71
|
return (
|
|
64
|
-
<Flexbox className={styles.container}
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
<
|
|
70
|
-
|
|
71
|
-
<
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
<Flexbox className={styles.container}>
|
|
73
|
+
{/* Header */}
|
|
74
|
+
<Flexbox align={'center'} className={styles.header} gap={8} horizontal>
|
|
75
|
+
<NotebookText className={styles.icon} size={16} />
|
|
76
|
+
<Flexbox flex={1}>
|
|
77
|
+
<div className={styles.title}>{document.title}</div>
|
|
78
|
+
</Flexbox>
|
|
79
|
+
<Flexbox gap={4} horizontal>
|
|
80
|
+
<CopyButton
|
|
81
|
+
content={document.content}
|
|
82
|
+
size={'small'}
|
|
83
|
+
title={t('builtins.lobe-notebook.actions.copy')}
|
|
84
|
+
/>
|
|
85
|
+
<ActionIcon
|
|
86
|
+
icon={PencilLine}
|
|
87
|
+
onClick={handleExpand}
|
|
88
|
+
size={'small'}
|
|
89
|
+
title={t('builtins.lobe-notebook.actions.edit')}
|
|
90
|
+
/>
|
|
91
|
+
</Flexbox>
|
|
75
92
|
</Flexbox>
|
|
76
|
-
{
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
93
|
+
{/* Content */}
|
|
94
|
+
<ScrollShadow className={styles.content} offset={12} size={12} style={{ maxHeight: 400 }}>
|
|
95
|
+
<Markdown style={{ overflow: 'unset', paddingBottom: 40 }} variant={'chat'}>
|
|
96
|
+
{document.content}
|
|
97
|
+
</Markdown>
|
|
98
|
+
</ScrollShadow>
|
|
99
|
+
|
|
100
|
+
{/* Floating expand button */}
|
|
101
|
+
<Button
|
|
102
|
+
className={styles.expandButton}
|
|
103
|
+
color={'default'}
|
|
104
|
+
icon={<Maximize2 size={14} />}
|
|
105
|
+
onClick={handleExpand}
|
|
106
|
+
shape={'round'}
|
|
107
|
+
variant={'outlined'}
|
|
108
|
+
>
|
|
109
|
+
{t('builtins.lobe-notebook.actions.expand')}
|
|
110
|
+
</Button>
|
|
81
111
|
</Flexbox>
|
|
82
112
|
);
|
|
83
113
|
});
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import type { BuiltinStreamingProps } from '@lobechat/types';
|
|
4
|
+
import { Flexbox } from '@lobehub/ui';
|
|
5
|
+
import { createStaticStyles } from 'antd-style';
|
|
6
|
+
import { NotebookText } from 'lucide-react';
|
|
7
|
+
import { memo } from 'react';
|
|
8
|
+
|
|
9
|
+
import BubblesLoading from '@/components/BubblesLoading';
|
|
10
|
+
import NeuralNetworkLoading from '@/components/NeuralNetworkLoading';
|
|
11
|
+
import StreamingMarkdown from '@/components/StreamingMarkdown';
|
|
12
|
+
|
|
13
|
+
import type { CreateDocumentArgs } from '../../../types';
|
|
14
|
+
|
|
15
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
16
|
+
container: css`
|
|
17
|
+
overflow: hidden;
|
|
18
|
+
|
|
19
|
+
width: 100%;
|
|
20
|
+
border: 1px solid ${cssVar.colorBorderSecondary};
|
|
21
|
+
border-radius: 16px;
|
|
22
|
+
|
|
23
|
+
background: ${cssVar.colorBgElevated};
|
|
24
|
+
`,
|
|
25
|
+
header: css`
|
|
26
|
+
padding-block: 10px;
|
|
27
|
+
padding-inline: 12px;
|
|
28
|
+
border-block-end: 1px solid ${cssVar.colorBorderSecondary};
|
|
29
|
+
`,
|
|
30
|
+
icon: css`
|
|
31
|
+
color: ${cssVar.colorPrimary};
|
|
32
|
+
`,
|
|
33
|
+
title: css`
|
|
34
|
+
overflow: hidden;
|
|
35
|
+
display: -webkit-box;
|
|
36
|
+
-webkit-box-orient: vertical;
|
|
37
|
+
-webkit-line-clamp: 1;
|
|
38
|
+
|
|
39
|
+
font-weight: 500;
|
|
40
|
+
color: ${cssVar.colorText};
|
|
41
|
+
`,
|
|
42
|
+
}));
|
|
43
|
+
|
|
44
|
+
export const CreateDocumentStreaming = memo<BuiltinStreamingProps<CreateDocumentArgs>>(
|
|
45
|
+
({ args }) => {
|
|
46
|
+
const { content, title } = args || {};
|
|
47
|
+
|
|
48
|
+
if (!content && !title) return null;
|
|
49
|
+
|
|
50
|
+
return (
|
|
51
|
+
<Flexbox className={styles.container}>
|
|
52
|
+
{/* Header */}
|
|
53
|
+
<Flexbox align={'center'} className={styles.header} gap={8} horizontal>
|
|
54
|
+
<NotebookText className={styles.icon} size={16} />
|
|
55
|
+
<Flexbox flex={1}>
|
|
56
|
+
<div className={styles.title}>{title}</div>
|
|
57
|
+
</Flexbox>
|
|
58
|
+
<NeuralNetworkLoading size={20} />
|
|
59
|
+
</Flexbox>
|
|
60
|
+
{/* Content */}
|
|
61
|
+
{!content ? (
|
|
62
|
+
<Flexbox paddingBlock={16} paddingInline={12}>
|
|
63
|
+
<BubblesLoading />
|
|
64
|
+
</Flexbox>
|
|
65
|
+
) : (
|
|
66
|
+
<StreamingMarkdown>{content}</StreamingMarkdown>
|
|
67
|
+
)}
|
|
68
|
+
</Flexbox>
|
|
69
|
+
);
|
|
70
|
+
},
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
CreateDocumentStreaming.displayName = 'CreateDocumentStreaming';
|
|
74
|
+
|
|
75
|
+
export default CreateDocumentStreaming;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type BuiltinStreaming } from '@lobechat/types';
|
|
2
|
+
|
|
3
|
+
import { NotebookApiName } from '../../types';
|
|
4
|
+
import { CreateDocumentStreaming } from './CreateDocument';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Notebook Streaming Components Registry
|
|
8
|
+
*
|
|
9
|
+
* Streaming components are used to render tool calls while arguments
|
|
10
|
+
* are still being generated, allowing real-time feedback to users.
|
|
11
|
+
*/
|
|
12
|
+
export const NotebookStreamings: Record<string, BuiltinStreaming> = {
|
|
13
|
+
[NotebookApiName.createDocument]: CreateDocumentStreaming as BuiltinStreaming,
|
|
14
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { memo, useEffect, useRef, useState } from 'react';
|
|
4
|
+
|
|
5
|
+
interface AnimatedNumberProps {
|
|
6
|
+
duration?: number;
|
|
7
|
+
formatter?: (value: number) => string;
|
|
8
|
+
value: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export const AnimatedNumber = memo<AnimatedNumberProps>(({ value, duration = 500, formatter }) => {
|
|
12
|
+
const [displayValue, setDisplayValue] = useState(value);
|
|
13
|
+
const frameRef = useRef<number>(undefined);
|
|
14
|
+
const startTimeRef = useRef<number>(undefined);
|
|
15
|
+
const startValueRef = useRef(value);
|
|
16
|
+
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
const startValue = startValueRef.current;
|
|
19
|
+
const diff = value - startValue;
|
|
20
|
+
|
|
21
|
+
if (diff === 0) return;
|
|
22
|
+
|
|
23
|
+
const animate = (currentTime: number) => {
|
|
24
|
+
if (!startTimeRef.current) {
|
|
25
|
+
startTimeRef.current = currentTime;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const elapsed = currentTime - startTimeRef.current;
|
|
29
|
+
const progress = Math.min(elapsed / duration, 1);
|
|
30
|
+
|
|
31
|
+
// easeOutCubic
|
|
32
|
+
const easeProgress = 1 - (1 - progress) ** 3;
|
|
33
|
+
const current = startValue + diff * easeProgress;
|
|
34
|
+
|
|
35
|
+
setDisplayValue(current);
|
|
36
|
+
|
|
37
|
+
if (progress < 1) {
|
|
38
|
+
frameRef.current = requestAnimationFrame(animate);
|
|
39
|
+
} else {
|
|
40
|
+
startValueRef.current = value;
|
|
41
|
+
startTimeRef.current = undefined;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
frameRef.current = requestAnimationFrame(animate);
|
|
46
|
+
|
|
47
|
+
return () => {
|
|
48
|
+
if (frameRef.current) {
|
|
49
|
+
cancelAnimationFrame(frameRef.current);
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}, [value, duration]);
|
|
53
|
+
|
|
54
|
+
return formatter ? formatter(displayValue) : Math.round(displayValue).toLocaleString();
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
AnimatedNumber.displayName = 'AnimatedNumber';
|
|
@@ -1,6 +1,18 @@
|
|
|
1
|
+
// Inspector components (customized tool call headers)
|
|
2
|
+
export { NotebookInspectors } from './Inspector';
|
|
3
|
+
|
|
4
|
+
// Intervention components (approval dialogs)
|
|
1
5
|
export { NotebookInterventions } from './Intervention';
|
|
6
|
+
|
|
7
|
+
// Placeholder components (loading states)
|
|
8
|
+
export { CreateDocumentPlaceholder, NotebookPlaceholders } from './Placeholder';
|
|
9
|
+
|
|
10
|
+
// Render components (read-only snapshots)
|
|
2
11
|
export { CreateDocument, NotebookRenders } from './Render';
|
|
3
12
|
|
|
13
|
+
// Streaming components
|
|
14
|
+
export { NotebookStreamings } from './Streaming';
|
|
15
|
+
|
|
4
16
|
// Re-export types and manifest for convenience
|
|
5
17
|
export { NotebookManifest } from '../manifest';
|
|
6
18
|
export * from '../types';
|
|
@@ -34,11 +34,12 @@ Note: The list of existing documents is automatically provided in the context, s
|
|
|
34
34
|
</workflow>
|
|
35
35
|
|
|
36
36
|
<best_practices>
|
|
37
|
-
- Use
|
|
37
|
+
- Use clean, concise titles without decorations or suffixes (e.g., use "The Last Letter" instead of "《The Last Letter》 - Short Story")
|
|
38
38
|
- Choose appropriate document types based on content nature
|
|
39
39
|
- For long content, consider breaking into multiple documents
|
|
40
40
|
- Use append mode when adding to existing documents
|
|
41
41
|
- Always confirm before deleting documents
|
|
42
|
+
- Do NOT include h1 headings in document content (the title field already serves as the document title)
|
|
42
43
|
</best_practices>
|
|
43
44
|
|
|
44
45
|
<response_format>
|