@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
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
3
|
import { Flexbox } from '@lobehub/ui';
|
|
4
|
-
import {
|
|
4
|
+
import { memo } from 'react';
|
|
5
5
|
|
|
6
6
|
import NavHeader from '@/features/NavHeader';
|
|
7
7
|
import WideScreenContainer from '@/features/WideScreenContainer';
|
|
8
8
|
import WideScreenButton from '@/features/WideScreenContainer/WideScreenButton';
|
|
9
9
|
|
|
10
10
|
import ImageWorkspace from './features/ImageWorkspace';
|
|
11
|
-
import SkeletonList from './features/ImageWorkspace/SkeletonList';
|
|
12
11
|
|
|
13
12
|
const DesktopImagePage = memo(() => {
|
|
14
13
|
return (
|
|
@@ -16,9 +15,7 @@ const DesktopImagePage = memo(() => {
|
|
|
16
15
|
<NavHeader right={<WideScreenButton />} />
|
|
17
16
|
<Flexbox height={'100%'} style={{ overflowY: 'auto', position: 'relative' }} width={'100%'}>
|
|
18
17
|
<WideScreenContainer height={'100%'} wrapperStyle={{ height: '100%' }}>
|
|
19
|
-
<
|
|
20
|
-
<ImageWorkspace />
|
|
21
|
-
</Suspense>
|
|
18
|
+
<ImageWorkspace />
|
|
22
19
|
</WideScreenContainer>
|
|
23
20
|
</Flexbox>
|
|
24
21
|
</>
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { Markdown, ScrollShadow } from '@lobehub/ui';
|
|
4
|
+
import { createStaticStyles } from 'antd-style';
|
|
5
|
+
import { memo, useCallback, useEffect, useRef, useState } from 'react';
|
|
6
|
+
|
|
7
|
+
const styles = createStaticStyles(({ css }) => ({
|
|
8
|
+
container: css`
|
|
9
|
+
padding-block: 12px;
|
|
10
|
+
padding-inline: 16px;
|
|
11
|
+
border-radius: 8px;
|
|
12
|
+
font-size: 14px;
|
|
13
|
+
`,
|
|
14
|
+
}));
|
|
15
|
+
|
|
16
|
+
interface StreamingMarkdownProps {
|
|
17
|
+
children?: string;
|
|
18
|
+
maxHeight?: number;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
const StreamingMarkdown = memo<StreamingMarkdownProps>(({ children, maxHeight = 400 }) => {
|
|
22
|
+
const containerRef = useRef<HTMLDivElement>(null);
|
|
23
|
+
const [userHasScrolled, setUserHasScrolled] = useState(false);
|
|
24
|
+
const isAutoScrollingRef = useRef(false);
|
|
25
|
+
|
|
26
|
+
// Handle user scroll detection
|
|
27
|
+
const handleScroll = useCallback(() => {
|
|
28
|
+
// Ignore scroll events triggered by auto-scroll
|
|
29
|
+
if (isAutoScrollingRef.current) return;
|
|
30
|
+
|
|
31
|
+
const container = containerRef.current;
|
|
32
|
+
if (!container) return;
|
|
33
|
+
|
|
34
|
+
// Check if user scrolled away from bottom
|
|
35
|
+
const distanceToBottom = container.scrollHeight - container.scrollTop - container.clientHeight;
|
|
36
|
+
const isAtBottom = distanceToBottom < 20;
|
|
37
|
+
|
|
38
|
+
// If user scrolled up, stop auto-scrolling
|
|
39
|
+
if (!isAtBottom) {
|
|
40
|
+
setUserHasScrolled(true);
|
|
41
|
+
}
|
|
42
|
+
}, []);
|
|
43
|
+
|
|
44
|
+
// Auto scroll to bottom when content changes (unless user has scrolled)
|
|
45
|
+
useEffect(() => {
|
|
46
|
+
if (userHasScrolled) return;
|
|
47
|
+
|
|
48
|
+
const container = containerRef.current;
|
|
49
|
+
if (!container) return;
|
|
50
|
+
|
|
51
|
+
isAutoScrollingRef.current = true;
|
|
52
|
+
requestAnimationFrame(() => {
|
|
53
|
+
container.scrollTop = container.scrollHeight;
|
|
54
|
+
// Reset the flag after scroll completes
|
|
55
|
+
requestAnimationFrame(() => {
|
|
56
|
+
isAutoScrollingRef.current = false;
|
|
57
|
+
});
|
|
58
|
+
});
|
|
59
|
+
}, [children, userHasScrolled]);
|
|
60
|
+
|
|
61
|
+
// Reset userHasScrolled when content is cleared (new stream starts)
|
|
62
|
+
useEffect(() => {
|
|
63
|
+
if (!children) {
|
|
64
|
+
setUserHasScrolled(false);
|
|
65
|
+
}
|
|
66
|
+
}, [children]);
|
|
67
|
+
|
|
68
|
+
if (!children) return null;
|
|
69
|
+
|
|
70
|
+
return (
|
|
71
|
+
<ScrollShadow
|
|
72
|
+
className={styles.container}
|
|
73
|
+
offset={12}
|
|
74
|
+
onScroll={handleScroll}
|
|
75
|
+
ref={containerRef}
|
|
76
|
+
size={12}
|
|
77
|
+
style={{ maxHeight }}
|
|
78
|
+
>
|
|
79
|
+
<Markdown animated style={{ overflow: 'unset' }} variant={'chat'}>
|
|
80
|
+
{children}
|
|
81
|
+
</Markdown>
|
|
82
|
+
</ScrollShadow>
|
|
83
|
+
);
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
StreamingMarkdown.displayName = 'StreamingMarkdown';
|
|
87
|
+
|
|
88
|
+
export default StreamingMarkdown;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { LOADING_FLAT } from '@lobechat/const';
|
|
2
1
|
import { type ChatToolResult, type ToolIntervention } from '@lobechat/types';
|
|
3
2
|
import { safeParsePartialJSON } from '@lobechat/utils';
|
|
4
3
|
import { Flexbox } from '@lobehub/ui';
|
|
@@ -20,6 +19,7 @@ interface RenderProps {
|
|
|
20
19
|
identifier: string;
|
|
21
20
|
intervention?: ToolIntervention;
|
|
22
21
|
isArgumentsStreaming?: boolean;
|
|
22
|
+
isToolCalling?: boolean;
|
|
23
23
|
/**
|
|
24
24
|
* ContentBlock ID (not the group message ID)
|
|
25
25
|
*/
|
|
@@ -52,6 +52,7 @@ const Render = memo<RenderProps>(
|
|
|
52
52
|
intervention,
|
|
53
53
|
toolMessageId,
|
|
54
54
|
isArgumentsStreaming,
|
|
55
|
+
isToolCalling,
|
|
55
56
|
}) => {
|
|
56
57
|
if (toolMessageId && intervention?.status === 'pending') {
|
|
57
58
|
return (
|
|
@@ -125,10 +126,7 @@ const Render = memo<RenderProps>(
|
|
|
125
126
|
/>
|
|
126
127
|
);
|
|
127
128
|
|
|
128
|
-
|
|
129
|
-
const inPlaceholder = result.content === LOADING_FLAT && type !== 'standalone';
|
|
130
|
-
|
|
131
|
-
if (inPlaceholder) return placeholder;
|
|
129
|
+
if (isToolCalling) return placeholder;
|
|
132
130
|
|
|
133
131
|
return (
|
|
134
132
|
<Suspense fallback={placeholder}>
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
+
import { LOADING_FLAT } from '@lobechat/const';
|
|
1
2
|
import { type ChatToolResult, type ToolIntervention } from '@lobechat/types';
|
|
2
3
|
import { AccordionItem, Flexbox, Skeleton } from '@lobehub/ui';
|
|
3
4
|
import { Divider } from 'antd';
|
|
4
5
|
import dynamic from 'next/dynamic';
|
|
5
6
|
import { memo, useEffect, useState } from 'react';
|
|
6
7
|
|
|
8
|
+
import { useChatStore } from '@/store/chat';
|
|
9
|
+
import { operationSelectors } from '@/store/chat/slices/operation/selectors';
|
|
7
10
|
import { useToolStore } from '@/store/tool';
|
|
8
11
|
import { toolSelectors } from '@/store/tool/selectors';
|
|
9
12
|
import { getBuiltinRender } from '@/tools/renders';
|
|
@@ -71,6 +74,16 @@ const Tool = memo<GroupToolProps>(
|
|
|
71
74
|
const hasStreamingRenderer = !!getBuiltinStreaming(identifier, apiName);
|
|
72
75
|
const forceShowStreamingRender = isArgumentsStreaming && hasStreamingRenderer;
|
|
73
76
|
|
|
77
|
+
// Get precise tool calling state from operation
|
|
78
|
+
const isToolCallingFromOperation = useChatStore(
|
|
79
|
+
operationSelectors.isMessageInToolCalling(assistantMessageId),
|
|
80
|
+
);
|
|
81
|
+
|
|
82
|
+
// Fallback: arguments completed but no final result yet
|
|
83
|
+
const isToolCallingFallback =
|
|
84
|
+
!isArgumentsStreaming && (!result || result.content === LOADING_FLAT || !result.content);
|
|
85
|
+
const isToolCalling = isToolCallingFromOperation || isToolCallingFallback;
|
|
86
|
+
|
|
74
87
|
const hasCustomRender = !!getBuiltinRender(identifier, apiName);
|
|
75
88
|
|
|
76
89
|
// Handle expand state changes with showPluginRender
|
|
@@ -138,6 +151,7 @@ const Tool = memo<GroupToolProps>(
|
|
|
138
151
|
identifier={identifier}
|
|
139
152
|
intervention={intervention}
|
|
140
153
|
isArgumentsStreaming={isArgumentsStreaming}
|
|
154
|
+
isToolCalling={isToolCalling}
|
|
141
155
|
messageId={assistantMessageId}
|
|
142
156
|
result={result}
|
|
143
157
|
setShowPluginRender={setShowPluginRender}
|
|
@@ -64,7 +64,7 @@ export default function PluginEmptyState() {
|
|
|
64
64
|
{t('dev.preview.empty.title')}
|
|
65
65
|
</Text>
|
|
66
66
|
<Text className={styles.description}>{t('dev.preview.empty.desc')}</Text>
|
|
67
|
-
<Space align="center"
|
|
67
|
+
<Space align="center" orientation="vertical">
|
|
68
68
|
<div className={styles.line} style={{ width: 128 }} />
|
|
69
69
|
<div className={styles.line} style={{ width: 96 }} />
|
|
70
70
|
<div className={styles.line} style={{ width: 48 }} />
|
|
@@ -93,6 +93,15 @@ export default {
|
|
|
93
93
|
'builtins.lobe-local-system.inspector.rename.result':
|
|
94
94
|
'<old>{{oldName}}</old> → <new>{{newName}}</new>',
|
|
95
95
|
'builtins.lobe-local-system.title': 'Local System',
|
|
96
|
+
'builtins.lobe-notebook.actions.copy': 'Copy',
|
|
97
|
+
'builtins.lobe-notebook.actions.creating': 'Creating document...',
|
|
98
|
+
'builtins.lobe-notebook.actions.edit': 'Edit',
|
|
99
|
+
'builtins.lobe-notebook.actions.expand': 'Expand',
|
|
100
|
+
'builtins.lobe-notebook.apiName.createDocument': 'Create document',
|
|
101
|
+
'builtins.lobe-notebook.apiName.deleteDocument': 'Delete document',
|
|
102
|
+
'builtins.lobe-notebook.apiName.getDocument': 'Get document',
|
|
103
|
+
'builtins.lobe-notebook.apiName.updateDocument': 'Update document',
|
|
104
|
+
'builtins.lobe-notebook.title': 'Notebook',
|
|
96
105
|
'builtins.lobe-page-agent.apiName.batchUpdate': 'Batch update nodes',
|
|
97
106
|
'builtins.lobe-page-agent.apiName.compareSnapshots': 'Compare snapshots',
|
|
98
107
|
'builtins.lobe-page-agent.apiName.convertToList': 'Convert to list',
|
|
@@ -185,7 +185,7 @@ const categorizeError = (
|
|
|
185
185
|
}
|
|
186
186
|
|
|
187
187
|
return {
|
|
188
|
-
errorMessage: error.message || AsyncTaskErrorType.ServerError,
|
|
188
|
+
errorMessage: error.message || error.error?.message || AsyncTaskErrorType.ServerError,
|
|
189
189
|
errorType: AsyncTaskErrorType.ServerError,
|
|
190
190
|
};
|
|
191
191
|
};
|