@lobehub/chat 1.82.0 → 1.82.2
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/desktop-local-tools-implement.mdc +80 -0
- package/.env.desktop +2 -1
- package/.github/scripts/pr-comment.js +4 -9
- package/CHANGELOG.md +51 -0
- package/changelog/v1.json +18 -0
- package/locales/ar/electron.json +38 -2
- package/locales/ar/plugin.json +51 -31
- package/locales/bg-BG/electron.json +38 -2
- package/locales/bg-BG/plugin.json +51 -31
- package/locales/de-DE/electron.json +38 -2
- package/locales/de-DE/plugin.json +29 -9
- package/locales/en-US/electron.json +38 -2
- package/locales/en-US/plugin.json +29 -9
- package/locales/es-ES/electron.json +38 -2
- package/locales/es-ES/plugin.json +51 -31
- package/locales/fa-IR/electron.json +38 -2
- package/locales/fa-IR/plugin.json +51 -31
- package/locales/fr-FR/electron.json +38 -2
- package/locales/fr-FR/plugin.json +51 -31
- package/locales/it-IT/electron.json +38 -2
- package/locales/it-IT/plugin.json +51 -31
- package/locales/ja-JP/electron.json +38 -2
- package/locales/ja-JP/plugin.json +51 -31
- package/locales/ko-KR/electron.json +38 -2
- package/locales/ko-KR/plugin.json +29 -9
- package/locales/nl-NL/electron.json +38 -2
- package/locales/nl-NL/plugin.json +51 -31
- package/locales/pl-PL/electron.json +38 -2
- package/locales/pl-PL/plugin.json +29 -9
- package/locales/pt-BR/electron.json +38 -2
- package/locales/pt-BR/plugin.json +51 -31
- package/locales/ru-RU/electron.json +38 -2
- package/locales/ru-RU/plugin.json +51 -31
- package/locales/tr-TR/electron.json +38 -2
- package/locales/tr-TR/plugin.json +51 -31
- package/locales/vi-VN/electron.json +38 -2
- package/locales/vi-VN/plugin.json +29 -9
- package/locales/zh-CN/electron.json +38 -2
- package/locales/zh-CN/plugin.json +30 -10
- package/locales/zh-TW/electron.json +38 -2
- package/locales/zh-TW/plugin.json +51 -31
- package/package.json +1 -1
- package/packages/electron-client-ipc/src/events/update.ts +3 -3
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Mode.tsx +222 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Option.tsx +104 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Sync.tsx +42 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/Waiting.tsx +203 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/Connection/index.tsx +57 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/UpdateModal.tsx +242 -0
- package/src/app/[variants]/(main)/_layout/Desktop/ElectronTitlebar/UpdateNotification.tsx +193 -0
- package/src/app/[variants]/(main)/_layout/Desktop/{Titlebar.tsx → ElectronTitlebar/index.tsx} +15 -1
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/BottomActions.tsx +3 -2
- package/src/app/[variants]/(main)/_layout/Desktop/index.tsx +1 -1
- package/src/app/[variants]/layout.tsx +2 -1
- package/src/config/aiModels/openrouter.ts +6 -6
- package/src/features/Conversation/components/MarkdownElements/LocalFile/Render/LocalFile.tsx +65 -0
- package/src/features/Conversation/components/MarkdownElements/LocalFile/Render/index.tsx +29 -0
- package/src/features/Conversation/components/MarkdownElements/LocalFile/index.ts +16 -0
- package/src/features/Conversation/components/MarkdownElements/index.ts +7 -1
- package/src/features/Conversation/components/MarkdownElements/remarkPlugins/__snapshots__/createRemarkSelfClosingTagPlugin.test.ts.snap +260 -0
- package/src/features/Conversation/components/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.test.ts +204 -0
- package/src/features/Conversation/components/MarkdownElements/remarkPlugins/createRemarkSelfClosingTagPlugin.ts +133 -0
- package/src/features/Conversation/components/MarkdownElements/type.ts +5 -1
- package/src/features/PluginDevModal/MCPManifestForm/ArgsInput.tsx +20 -0
- package/src/features/PluginDevModal/MCPManifestForm/MCPTypeSelect.tsx +176 -0
- package/src/features/PluginDevModal/MCPManifestForm/index.tsx +289 -0
- package/src/features/PluginDevModal/MCPManifestForm/utils.test.ts +262 -0
- package/src/features/PluginDevModal/MCPManifestForm/utils.ts +151 -0
- package/src/features/PluginDevModal/index.tsx +31 -22
- package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +1 -1
- package/src/libs/mcp/__tests__/__snapshots__/index.test.ts.snap +0 -56
- package/src/locales/default/electron.ts +38 -2
- package/src/locales/default/plugin.ts +28 -8
- package/src/server/modules/ElectronIPCClient/index.ts +36 -0
- package/src/server/routers/lambda/session.ts +2 -6
- package/src/server/routers/tools/mcp.ts +6 -0
- package/src/server/services/file/impls/index.ts +9 -1
- package/src/server/services/file/impls/local.test.ts +299 -0
- package/src/server/services/file/impls/local.ts +183 -0
- package/src/server/services/mcp/index.ts +26 -0
- package/src/services/aiModel/index.ts +5 -1
- package/src/services/aiProvider/index.ts +5 -1
- package/src/services/electron/autoUpdate.ts +4 -0
- package/src/services/file/index.ts +5 -1
- package/src/services/mcp.ts +13 -2
- package/src/services/message/index.ts +5 -1
- package/src/services/plugin/index.ts +5 -1
- package/src/services/session/index.ts +5 -1
- package/src/services/tableViewer/desktop.ts +15 -0
- package/src/services/tableViewer/index.ts +4 -1
- package/src/services/thread/index.ts +5 -1
- package/src/services/topic/index.ts +5 -1
- package/src/services/user/index.ts +5 -1
- package/src/store/electron/actions/app.ts +59 -0
- package/src/store/electron/actions/sync.ts +5 -1
- package/src/store/electron/initialState.ts +3 -1
- package/src/store/electron/store.ts +6 -1
- package/src/store/tool/slices/customPlugin/action.ts +16 -4
- package/src/utils/client/GlobalAgentContextManager.ts +85 -0
- package/src/utils/promptTemplate.test.ts +78 -0
- package/src/utils/promptTemplate.ts +17 -0
- package/src/features/PluginDevModal/MCPManifestForm.tsx +0 -164
package/src/app/[variants]/(main)/_layout/Desktop/{Titlebar.tsx → ElectronTitlebar/index.tsx}
RENAMED
@@ -1,11 +1,20 @@
|
|
1
1
|
import { memo } from 'react';
|
2
2
|
import { Flexbox } from 'react-layout-kit';
|
3
3
|
|
4
|
+
import { useElectronStore } from '@/store/electron';
|
4
5
|
import { electronStylish } from '@/styles/electron';
|
5
6
|
|
7
|
+
import Connection from './Connection';
|
8
|
+
import { UpdateModal } from './UpdateModal';
|
9
|
+
import { UpdateNotification } from './UpdateNotification';
|
10
|
+
|
6
11
|
export const TITLE_BAR_HEIGHT = 36;
|
7
12
|
|
8
13
|
const TitleBar = memo(() => {
|
14
|
+
const initElectronAppState = useElectronStore((s) => s.useInitElectronAppState);
|
15
|
+
|
16
|
+
initElectronAppState();
|
17
|
+
|
9
18
|
return (
|
10
19
|
<Flexbox
|
11
20
|
align={'center'}
|
@@ -19,7 +28,12 @@ const TitleBar = memo(() => {
|
|
19
28
|
>
|
20
29
|
<div />
|
21
30
|
<div>{/* TODO */}</div>
|
22
|
-
|
31
|
+
|
32
|
+
<Flexbox className={electronStylish.nodrag} gap={8} horizontal>
|
33
|
+
<UpdateNotification />
|
34
|
+
<Connection />
|
35
|
+
</Flexbox>
|
36
|
+
<UpdateModal />
|
23
37
|
</Flexbox>
|
24
38
|
);
|
25
39
|
});
|
@@ -3,6 +3,7 @@ import { Book, Github } from 'lucide-react';
|
|
3
3
|
import Link from 'next/link';
|
4
4
|
import { memo } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
|
+
import { Flexbox } from 'react-layout-kit';
|
6
7
|
|
7
8
|
import { DOCUMENTS_REFER_URL, GITHUB } from '@/const/url';
|
8
9
|
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
|
@@ -12,7 +13,7 @@ const BottomActions = memo(() => {
|
|
12
13
|
const { hideGitHub, hideDocs } = useServerConfigStore(featureFlagsSelectors);
|
13
14
|
|
14
15
|
return (
|
15
|
-
|
16
|
+
<Flexbox gap={8}>
|
16
17
|
{!hideGitHub && (
|
17
18
|
<Link aria-label={'GitHub'} href={GITHUB} target={'_blank'}>
|
18
19
|
<ActionIcon icon={Github} placement={'right'} title={'GitHub'} />
|
@@ -23,7 +24,7 @@ const BottomActions = memo(() => {
|
|
23
24
|
<ActionIcon icon={Book} placement={'right'} title={t('document')} />
|
24
25
|
</Link>
|
25
26
|
)}
|
26
|
-
|
27
|
+
</Flexbox>
|
27
28
|
);
|
28
29
|
});
|
29
30
|
|
@@ -14,9 +14,9 @@ import { usePlatform } from '@/hooks/usePlatform';
|
|
14
14
|
import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
|
15
15
|
import { HotkeyScopeEnum } from '@/types/hotkey';
|
16
16
|
|
17
|
+
import TitleBar, { TITLE_BAR_HEIGHT } from './ElectronTitlebar';
|
17
18
|
import RegisterHotkeys from './RegisterHotkeys';
|
18
19
|
import SideBar from './SideBar';
|
19
|
-
import TitleBar, { TITLE_BAR_HEIGHT } from './Titlebar';
|
20
20
|
|
21
21
|
const CloudBanner = dynamic(() => import('@/features/AlertBanner/CloudBanner'));
|
22
22
|
|
@@ -7,6 +7,7 @@ import { isRtlLang } from 'rtl-detect';
|
|
7
7
|
|
8
8
|
import Analytics from '@/components/Analytics';
|
9
9
|
import { DEFAULT_LANG } from '@/const/locale';
|
10
|
+
import { isDesktop } from '@/const/version';
|
10
11
|
import PWAInstall from '@/features/PWAInstall';
|
11
12
|
import AuthProvider from '@/layout/AuthProvider';
|
12
13
|
import GlobalProvider from '@/layout/GlobalProvider';
|
@@ -78,7 +79,7 @@ export const generateViewport = async (props: DynamicLayoutProps): ResolvingView
|
|
78
79
|
|
79
80
|
export const generateStaticParams = () => {
|
80
81
|
const themes: ThemeAppearance[] = ['dark', 'light'];
|
81
|
-
const mobileOptions = [true, false];
|
82
|
+
const mobileOptions = isDesktop ? [false] : [true, false];
|
82
83
|
// only static for serveral page, other go to dynamtic
|
83
84
|
const staticLocales: Locales[] = [DEFAULT_LANG, 'zh-CN'];
|
84
85
|
|
@@ -20,7 +20,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
20
20
|
description:
|
21
21
|
'o3 是一款全能强大的模型,在多个领域表现出色。它为数学、科学、编程和视觉推理任务树立了新标杆。它也擅长技术写作和指令遵循。用户可利用它分析文本、代码和图像,解决多步骤的复杂问题。',
|
22
22
|
displayName: 'o3',
|
23
|
-
id: 'o3',
|
23
|
+
id: 'openai/o3',
|
24
24
|
maxOutput: 100_000,
|
25
25
|
pricing: {
|
26
26
|
cachedInput: 2.5,
|
@@ -79,7 +79,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
79
79
|
description:
|
80
80
|
'GPT-4.1 是我们用于复杂任务的旗舰模型。它非常适合跨领域解决问题。',
|
81
81
|
displayName: 'GPT-4.1',
|
82
|
-
id: 'gpt-4.1',
|
82
|
+
id: 'openai/gpt-4.1',
|
83
83
|
maxOutput: 32_768,
|
84
84
|
pricing: {
|
85
85
|
cachedInput: 0.5,
|
@@ -98,7 +98,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
98
98
|
description:
|
99
99
|
'GPT-4.1 mini 提供了智能、速度和成本之间的平衡,使其成为许多用例中有吸引力的模型。',
|
100
100
|
displayName: 'GPT-4.1 mini',
|
101
|
-
id: 'gpt-4.1-mini',
|
101
|
+
id: 'openai/gpt-4.1-mini',
|
102
102
|
maxOutput: 32_768,
|
103
103
|
pricing: {
|
104
104
|
cachedInput: 0.1,
|
@@ -117,7 +117,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
117
117
|
description:
|
118
118
|
'GPT-4.1 nano 是最快,最具成本效益的GPT-4.1模型。',
|
119
119
|
displayName: 'GPT-4.1 nano',
|
120
|
-
id: 'gpt-4.1-nano',
|
120
|
+
id: 'openai/gpt-4.1-nano',
|
121
121
|
maxOutput: 32_768,
|
122
122
|
pricing: {
|
123
123
|
cachedInput: 0.025,
|
@@ -136,7 +136,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
136
136
|
description:
|
137
137
|
'o3-mini 高推理等级版,在与 o1-mini 相同的成本和延迟目标下提供高智能。',
|
138
138
|
displayName: 'o3-mini (high)',
|
139
|
-
id: 'o3-mini-high',
|
139
|
+
id: 'openai/o3-mini-high',
|
140
140
|
maxOutput: 100_000,
|
141
141
|
pricing: {
|
142
142
|
cachedInput: 0.55,
|
@@ -155,7 +155,7 @@ const openrouterChatModels: AIChatModelCard[] = [
|
|
155
155
|
description:
|
156
156
|
'o3-mini 在与 o1-mini 相同的成本和延迟目标下提供高智能。',
|
157
157
|
displayName: 'o3-mini',
|
158
|
-
id: 'o3-mini',
|
158
|
+
id: 'openai/o3-mini',
|
159
159
|
maxOutput: 100_000,
|
160
160
|
pricing: {
|
161
161
|
cachedInput: 0.55,
|
@@ -0,0 +1,65 @@
|
|
1
|
+
import { createStyles } from 'antd-style';
|
2
|
+
import React from 'react';
|
3
|
+
import { Flexbox } from 'react-layout-kit';
|
4
|
+
|
5
|
+
import FileIcon from '@/components/FileIcon';
|
6
|
+
import { localFileService } from '@/services/electron/localFileService';
|
7
|
+
|
8
|
+
const useStyles = createStyles(({ css, token }) => ({
|
9
|
+
container: css`
|
10
|
+
cursor: pointer;
|
11
|
+
|
12
|
+
padding-block: 2px;
|
13
|
+
padding-inline: 4px 8px;
|
14
|
+
border-radius: 4px;
|
15
|
+
|
16
|
+
color: ${token.colorTextSecondary};
|
17
|
+
|
18
|
+
:hover {
|
19
|
+
color: ${token.colorText};
|
20
|
+
background: ${token.colorFillTertiary};
|
21
|
+
}
|
22
|
+
`,
|
23
|
+
title: css`
|
24
|
+
overflow: hidden;
|
25
|
+
display: block;
|
26
|
+
|
27
|
+
line-height: 20px;
|
28
|
+
color: inherit;
|
29
|
+
text-overflow: ellipsis;
|
30
|
+
white-space: nowrap;
|
31
|
+
`,
|
32
|
+
}));
|
33
|
+
|
34
|
+
const LocalFile = ({
|
35
|
+
name,
|
36
|
+
path,
|
37
|
+
isDirectory,
|
38
|
+
}: {
|
39
|
+
isDirectory: boolean;
|
40
|
+
name: string;
|
41
|
+
path: string;
|
42
|
+
}) => {
|
43
|
+
const { styles } = useStyles();
|
44
|
+
const handleClick = () => {
|
45
|
+
localFileService.openLocalFileOrFolder(path, isDirectory);
|
46
|
+
};
|
47
|
+
|
48
|
+
return (
|
49
|
+
<Flexbox
|
50
|
+
align={'center'}
|
51
|
+
className={styles.container}
|
52
|
+
gap={4}
|
53
|
+
horizontal
|
54
|
+
onClick={handleClick}
|
55
|
+
style={{ display: 'inline-flex', verticalAlign: 'middle' }}
|
56
|
+
>
|
57
|
+
<FileIcon fileName={name} isDirectory={isDirectory} size={22} variant={'pure'} />
|
58
|
+
<Flexbox align={'baseline'} gap={4} horizontal style={{ overflow: 'hidden', width: '100%' }}>
|
59
|
+
<div className={styles.title}>{name}</div>
|
60
|
+
</Flexbox>
|
61
|
+
</Flexbox>
|
62
|
+
);
|
63
|
+
};
|
64
|
+
|
65
|
+
export default LocalFile;
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import isEqual from 'fast-deep-equal';
|
2
|
+
import React, { memo } from 'react';
|
3
|
+
|
4
|
+
import { MarkdownElementProps } from '../../type';
|
5
|
+
import LocalFile from './LocalFile';
|
6
|
+
|
7
|
+
interface LocalFileProps {
|
8
|
+
isDirectory: boolean;
|
9
|
+
name: string;
|
10
|
+
path: string;
|
11
|
+
}
|
12
|
+
|
13
|
+
const Render = memo<MarkdownElementProps<LocalFileProps>>(({ node }) => {
|
14
|
+
// 从 node.properties 中提取属性
|
15
|
+
const { name, path, isDirectory } = node?.properties || {};
|
16
|
+
|
17
|
+
if (!name || !path) {
|
18
|
+
// 如果缺少必要属性,可以选择渲染错误提示或 null
|
19
|
+
console.error('LocalFile Render component missing required properties:', node?.properties);
|
20
|
+
return null; // 或者返回一个错误占位符
|
21
|
+
}
|
22
|
+
|
23
|
+
// isDirectory 属性可能为 true (来自插件) 或 undefined,我们需要确保它是 boolean
|
24
|
+
const isDir = isDirectory === true;
|
25
|
+
|
26
|
+
return <LocalFile isDirectory={isDir} name={name} path={path} />;
|
27
|
+
}, isEqual);
|
28
|
+
|
29
|
+
export default Render;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
import { FC } from 'react';
|
2
|
+
|
3
|
+
import { createRemarkSelfClosingTagPlugin } from '../remarkPlugins/createRemarkSelfClosingTagPlugin';
|
4
|
+
import { MarkdownElement, MarkdownElementProps } from '../type';
|
5
|
+
import RenderComponent from './Render';
|
6
|
+
|
7
|
+
// 定义此元素的标签名
|
8
|
+
const tag = 'localFile';
|
9
|
+
|
10
|
+
const LocalFileElement: MarkdownElement = {
|
11
|
+
Component: RenderComponent as FC<MarkdownElementProps>,
|
12
|
+
remarkPlugin: createRemarkSelfClosingTagPlugin(tag),
|
13
|
+
tag,
|
14
|
+
};
|
15
|
+
|
16
|
+
export default LocalFileElement;
|
@@ -1,6 +1,12 @@
|
|
1
1
|
import LobeArtifact from './LobeArtifact';
|
2
2
|
import LobeThinking from './LobeThinking';
|
3
|
+
import LocalFile from './LocalFile';
|
3
4
|
import Thinking from './Thinking';
|
4
5
|
import { MarkdownElement } from './type';
|
5
6
|
|
6
|
-
export const markdownElements: MarkdownElement[] = [
|
7
|
+
export const markdownElements: MarkdownElement[] = [
|
8
|
+
Thinking,
|
9
|
+
LobeArtifact,
|
10
|
+
LobeThinking,
|
11
|
+
LocalFile,
|
12
|
+
];
|
@@ -0,0 +1,260 @@
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
2
|
+
|
3
|
+
exports[`createRemarkSelfClosingTagPlugin > should handle tag within a list item and generate snapshot 1`] = `
|
4
|
+
{
|
5
|
+
"children": [
|
6
|
+
{
|
7
|
+
"children": [
|
8
|
+
{
|
9
|
+
"checked": null,
|
10
|
+
"children": [
|
11
|
+
{
|
12
|
+
"children": [
|
13
|
+
{
|
14
|
+
"position": {
|
15
|
+
"end": {
|
16
|
+
"column": 26,
|
17
|
+
"line": 2,
|
18
|
+
"offset": 26,
|
19
|
+
},
|
20
|
+
"start": {
|
21
|
+
"column": 4,
|
22
|
+
"line": 2,
|
23
|
+
"offset": 4,
|
24
|
+
},
|
25
|
+
},
|
26
|
+
"type": "text",
|
27
|
+
"value": "文件名:飞机全书 一部明晰可见的历史.pdf",
|
28
|
+
},
|
29
|
+
],
|
30
|
+
"position": {
|
31
|
+
"end": {
|
32
|
+
"column": 26,
|
33
|
+
"line": 2,
|
34
|
+
"offset": 26,
|
35
|
+
},
|
36
|
+
"start": {
|
37
|
+
"column": 4,
|
38
|
+
"line": 2,
|
39
|
+
"offset": 4,
|
40
|
+
},
|
41
|
+
},
|
42
|
+
"type": "paragraph",
|
43
|
+
},
|
44
|
+
{
|
45
|
+
"children": [
|
46
|
+
{
|
47
|
+
"checked": null,
|
48
|
+
"children": [
|
49
|
+
{
|
50
|
+
"children": [
|
51
|
+
{
|
52
|
+
"position": {
|
53
|
+
"end": {
|
54
|
+
"column": 10,
|
55
|
+
"line": 3,
|
56
|
+
"offset": 36,
|
57
|
+
},
|
58
|
+
"start": {
|
59
|
+
"column": 6,
|
60
|
+
"line": 3,
|
61
|
+
"offset": 32,
|
62
|
+
},
|
63
|
+
},
|
64
|
+
"type": "text",
|
65
|
+
"value": "路径1:",
|
66
|
+
},
|
67
|
+
{
|
68
|
+
"data": {
|
69
|
+
"hName": "localFile",
|
70
|
+
"hProperties": {
|
71
|
+
"name": "飞机全书 一部明晰可见的历史.pdf",
|
72
|
+
"path": "/Users/abc/Zotero/storage/ASBMAURK/飞机全书 一部明晰可见的历史.pdf",
|
73
|
+
},
|
74
|
+
},
|
75
|
+
"type": "localFile",
|
76
|
+
},
|
77
|
+
],
|
78
|
+
"position": {
|
79
|
+
"end": {
|
80
|
+
"column": 110,
|
81
|
+
"line": 3,
|
82
|
+
"offset": 136,
|
83
|
+
},
|
84
|
+
"start": {
|
85
|
+
"column": 6,
|
86
|
+
"line": 3,
|
87
|
+
"offset": 32,
|
88
|
+
},
|
89
|
+
},
|
90
|
+
"type": "paragraph",
|
91
|
+
},
|
92
|
+
],
|
93
|
+
"position": {
|
94
|
+
"end": {
|
95
|
+
"column": 110,
|
96
|
+
"line": 3,
|
97
|
+
"offset": 136,
|
98
|
+
},
|
99
|
+
"start": {
|
100
|
+
"column": 4,
|
101
|
+
"line": 3,
|
102
|
+
"offset": 30,
|
103
|
+
},
|
104
|
+
},
|
105
|
+
"spread": false,
|
106
|
+
"type": "listItem",
|
107
|
+
},
|
108
|
+
{
|
109
|
+
"checked": null,
|
110
|
+
"children": [
|
111
|
+
{
|
112
|
+
"children": [
|
113
|
+
{
|
114
|
+
"position": {
|
115
|
+
"end": {
|
116
|
+
"column": 56,
|
117
|
+
"line": 4,
|
118
|
+
"offset": 192,
|
119
|
+
},
|
120
|
+
"start": {
|
121
|
+
"column": 6,
|
122
|
+
"line": 4,
|
123
|
+
"offset": 142,
|
124
|
+
},
|
125
|
+
},
|
126
|
+
"type": "text",
|
127
|
+
"value": "路径2:/Users/abc/Downloads/测试 PDF/飞机全书 一部明晰可见的历史.pdf",
|
128
|
+
},
|
129
|
+
],
|
130
|
+
"position": {
|
131
|
+
"end": {
|
132
|
+
"column": 56,
|
133
|
+
"line": 4,
|
134
|
+
"offset": 192,
|
135
|
+
},
|
136
|
+
"start": {
|
137
|
+
"column": 6,
|
138
|
+
"line": 4,
|
139
|
+
"offset": 142,
|
140
|
+
},
|
141
|
+
},
|
142
|
+
"type": "paragraph",
|
143
|
+
},
|
144
|
+
],
|
145
|
+
"position": {
|
146
|
+
"end": {
|
147
|
+
"column": 56,
|
148
|
+
"line": 4,
|
149
|
+
"offset": 192,
|
150
|
+
},
|
151
|
+
"start": {
|
152
|
+
"column": 4,
|
153
|
+
"line": 4,
|
154
|
+
"offset": 140,
|
155
|
+
},
|
156
|
+
},
|
157
|
+
"spread": false,
|
158
|
+
"type": "listItem",
|
159
|
+
},
|
160
|
+
],
|
161
|
+
"ordered": false,
|
162
|
+
"position": {
|
163
|
+
"end": {
|
164
|
+
"column": 56,
|
165
|
+
"line": 4,
|
166
|
+
"offset": 192,
|
167
|
+
},
|
168
|
+
"start": {
|
169
|
+
"column": 4,
|
170
|
+
"line": 3,
|
171
|
+
"offset": 30,
|
172
|
+
},
|
173
|
+
},
|
174
|
+
"spread": false,
|
175
|
+
"start": null,
|
176
|
+
"type": "list",
|
177
|
+
},
|
178
|
+
],
|
179
|
+
"position": {
|
180
|
+
"end": {
|
181
|
+
"column": 56,
|
182
|
+
"line": 4,
|
183
|
+
"offset": 192,
|
184
|
+
},
|
185
|
+
"start": {
|
186
|
+
"column": 1,
|
187
|
+
"line": 2,
|
188
|
+
"offset": 1,
|
189
|
+
},
|
190
|
+
},
|
191
|
+
"spread": false,
|
192
|
+
"type": "listItem",
|
193
|
+
},
|
194
|
+
],
|
195
|
+
"ordered": true,
|
196
|
+
"position": {
|
197
|
+
"end": {
|
198
|
+
"column": 56,
|
199
|
+
"line": 4,
|
200
|
+
"offset": 192,
|
201
|
+
},
|
202
|
+
"start": {
|
203
|
+
"column": 1,
|
204
|
+
"line": 2,
|
205
|
+
"offset": 1,
|
206
|
+
},
|
207
|
+
},
|
208
|
+
"spread": false,
|
209
|
+
"start": 1,
|
210
|
+
"type": "list",
|
211
|
+
},
|
212
|
+
{
|
213
|
+
"children": [
|
214
|
+
{
|
215
|
+
"position": {
|
216
|
+
"end": {
|
217
|
+
"column": 75,
|
218
|
+
"line": 6,
|
219
|
+
"offset": 268,
|
220
|
+
},
|
221
|
+
"start": {
|
222
|
+
"column": 1,
|
223
|
+
"line": 6,
|
224
|
+
"offset": 194,
|
225
|
+
},
|
226
|
+
},
|
227
|
+
"type": "text",
|
228
|
+
"value": "这是一本 PDF 格式的书,并且在你的 Zotero 和 Downloads 文件夹里都能找到。如果需要进一步操作,比如阅读或者提取内容,可以告诉我",
|
229
|
+
},
|
230
|
+
],
|
231
|
+
"position": {
|
232
|
+
"end": {
|
233
|
+
"column": 75,
|
234
|
+
"line": 6,
|
235
|
+
"offset": 268,
|
236
|
+
},
|
237
|
+
"start": {
|
238
|
+
"column": 1,
|
239
|
+
"line": 6,
|
240
|
+
"offset": 194,
|
241
|
+
},
|
242
|
+
},
|
243
|
+
"type": "paragraph",
|
244
|
+
},
|
245
|
+
],
|
246
|
+
"position": {
|
247
|
+
"end": {
|
248
|
+
"column": 1,
|
249
|
+
"line": 7,
|
250
|
+
"offset": 269,
|
251
|
+
},
|
252
|
+
"start": {
|
253
|
+
"column": 1,
|
254
|
+
"line": 1,
|
255
|
+
"offset": 0,
|
256
|
+
},
|
257
|
+
},
|
258
|
+
"type": "root",
|
259
|
+
}
|
260
|
+
`;
|