@lobehub/chat 1.11.1 → 1.11.3
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/.nvmrc +1 -1
- package/CHANGELOG.md +42 -0
- package/Dockerfile.database +70 -22
- package/README.md +1 -1
- package/README.zh-CN.md +1 -1
- package/docs/self-hosting/server-database/vercel.mdx +78 -75
- package/docs/self-hosting/start.zh-CN.mdx +2 -2
- package/docs/usage/providers/siliconcloud.mdx +4 -3
- package/docs/usage/providers/siliconcloud.zh-CN.mdx +0 -1
- package/locales/ar/common.json +3 -0
- package/locales/ar/components.json +60 -0
- package/locales/ar/setting.json +5 -0
- package/locales/bg-BG/common.json +3 -0
- package/locales/bg-BG/components.json +60 -0
- package/locales/bg-BG/setting.json +5 -0
- package/locales/de-DE/common.json +3 -0
- package/locales/de-DE/components.json +60 -0
- package/locales/de-DE/setting.json +5 -0
- package/locales/en-US/common.json +3 -0
- package/locales/en-US/components.json +60 -0
- package/locales/en-US/setting.json +5 -0
- package/locales/es-ES/common.json +3 -0
- package/locales/es-ES/components.json +60 -0
- package/locales/es-ES/setting.json +5 -0
- package/locales/fr-FR/common.json +3 -0
- package/locales/fr-FR/components.json +60 -0
- package/locales/fr-FR/setting.json +5 -0
- package/locales/it-IT/common.json +3 -0
- package/locales/it-IT/components.json +60 -0
- package/locales/it-IT/setting.json +5 -0
- package/locales/ja-JP/common.json +3 -0
- package/locales/ja-JP/components.json +60 -0
- package/locales/ja-JP/setting.json +5 -0
- package/locales/ko-KR/common.json +3 -0
- package/locales/ko-KR/components.json +60 -0
- package/locales/ko-KR/setting.json +5 -0
- package/locales/nl-NL/common.json +3 -0
- package/locales/nl-NL/components.json +60 -0
- package/locales/nl-NL/setting.json +5 -0
- package/locales/pl-PL/common.json +3 -0
- package/locales/pl-PL/components.json +60 -0
- package/locales/pl-PL/setting.json +5 -0
- package/locales/pt-BR/common.json +3 -0
- package/locales/pt-BR/components.json +60 -0
- package/locales/pt-BR/setting.json +5 -0
- package/locales/ru-RU/common.json +3 -0
- package/locales/ru-RU/components.json +60 -0
- package/locales/ru-RU/setting.json +5 -0
- package/locales/tr-TR/common.json +3 -0
- package/locales/tr-TR/components.json +60 -0
- package/locales/tr-TR/setting.json +5 -0
- package/locales/vi-VN/common.json +3 -0
- package/locales/vi-VN/components.json +60 -0
- package/locales/vi-VN/setting.json +5 -0
- package/locales/zh-CN/common.json +3 -0
- package/locales/zh-CN/components.json +60 -0
- package/locales/zh-CN/error.json +1 -1
- package/locales/zh-CN/setting.json +6 -1
- package/locales/zh-TW/common.json +3 -0
- package/locales/zh-TW/components.json +60 -0
- package/locales/zh-TW/setting.json +5 -0
- package/next.config.mjs +67 -66
- package/package.json +20 -8
- package/src/app/(main)/@nav/_layout/Desktop/TopActions.test.tsx +11 -0
- package/src/app/(main)/@nav/_layout/Desktop/TopActions.tsx +13 -1
- package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +3 -22
- package/src/components/FileIcon/config.ts +12 -0
- package/src/components/FileIcon/index.tsx +30 -0
- package/src/components/FunctionModal/createModalHooks.ts +46 -0
- package/src/components/FunctionModal/index.ts +1 -0
- package/src/components/FunctionModal/style.tsx +39 -0
- package/src/components/GoBack/index.tsx +46 -0
- package/src/components/PanelTitle/index.tsx +41 -0
- package/src/components/RepoIcon/index.tsx +22 -0
- package/src/components/SidebarHeader/index.tsx +4 -2
- package/src/components/TipGuide/index.tsx +150 -0
- package/src/config/featureFlags/schema.ts +6 -0
- package/src/config/file.ts +6 -0
- package/src/config/knowledge.ts +17 -0
- package/src/const/settings/llm.ts +1 -0
- package/src/const/settings/systemAgent.ts +1 -0
- package/src/database/client/models/message.ts +5 -0
- package/src/features/Conversation/Messages/Default.tsx +1 -2
- package/src/libs/agent-runtime/AgentRuntime.ts +9 -2
- package/src/libs/agent-runtime/BaseAI.ts +14 -1
- package/src/libs/agent-runtime/qwen/index.ts +3 -4
- package/src/libs/agent-runtime/types/embeddings.ts +43 -0
- package/src/libs/agent-runtime/types/index.ts +1 -0
- package/src/libs/agent-runtime/utils/openaiCompatibleFactory/index.ts +25 -2
- package/src/libs/langchain/file.ts +29 -0
- package/src/libs/langchain/index.ts +1 -0
- package/src/libs/langchain/loaders/code/__tests__/index.test.ts +34 -0
- package/src/libs/langchain/loaders/code/__tests__/long.json +250 -0
- package/src/libs/langchain/loaders/code/__tests__/long.txt +885 -0
- package/src/libs/langchain/loaders/code/index.ts +15 -0
- package/src/libs/langchain/loaders/config.ts +6 -0
- package/src/libs/langchain/loaders/docx/index.ts +13 -0
- package/src/libs/langchain/loaders/index.ts +98 -0
- package/src/libs/langchain/loaders/markdown/__tests__/demo.mdx +325 -0
- package/src/libs/langchain/loaders/markdown/__tests__/index.test.ts +13 -0
- package/src/libs/langchain/loaders/markdown/index.ts +9 -0
- package/src/libs/langchain/loaders/pdf/index.ts +7 -0
- package/src/libs/langchain/loaders/pptx/index.ts +7 -0
- package/src/libs/langchain/loaders/txt/__tests__/index.test.ts +54 -0
- package/src/libs/langchain/loaders/txt/__tests__/long.json +38 -0
- package/src/libs/langchain/loaders/txt/__tests__/pg24022.txt +83 -0
- package/src/libs/langchain/loaders/txt/index.ts +9 -0
- package/src/libs/langchain/types.ts +1 -0
- package/src/libs/unstructured/__tests__/fixtures/image-parse/fast-partition-none-output.json +3258 -0
- package/src/libs/unstructured/__tests__/fixtures/image-parse/fast-partition-none-raw.json +3255 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/auto-partition-basic-output.json +347 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/auto-partition-basic-raw.json +131 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/auto-partition-raw.json +276 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/fast-partition-basic-output.json +1865 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/fast-partition-basic-raw.json +111 -0
- package/src/libs/unstructured/__tests__/fixtures/table-parse/fast-partition-raw.json +1892 -0
- package/src/libs/unstructured/__tests__/index.test.ts +165 -0
- package/src/libs/unstructured/index.ts +166 -0
- package/src/locales/default/common.ts +3 -0
- package/src/locales/default/components.ts +62 -0
- package/src/locales/default/setting.ts +5 -0
- package/src/store/file/initialState.ts +1 -1
- package/src/store/file/selectors.ts +1 -1
- package/src/store/file/store.ts +1 -1
- package/src/store/global/initialState.ts +5 -0
- package/src/store/global/selectors.ts +4 -0
- package/src/store/serverConfig/selectors.test.ts +1 -0
- package/src/types/user/index.ts +12 -4
- package/src/types/user/settings/systemAgent.ts +1 -0
- package/src/utils/colorUtils.ts +19 -0
- package/src/utils/sleep.ts +4 -0
- /package/src/store/file/slices/{images → chat}/action.test.ts +0 -0
- /package/src/store/file/slices/{images → chat}/action.ts +0 -0
- /package/src/store/file/slices/{images → chat}/index.ts +0 -0
- /package/src/store/file/slices/{images → chat}/initialState.ts +0 -0
- /package/src/store/file/slices/{images → chat}/selectors.test.ts +0 -0
- /package/src/store/file/slices/{images → chat}/selectors.ts +0 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import { UnstructuredClient } from 'unstructured-client';
|
|
3
|
+
import { Strategy } from 'unstructured-client/sdk/models/shared';
|
|
4
|
+
import { ChunkingStrategy } from 'unstructured-client/sdk/models/shared/partitionparameters';
|
|
5
|
+
import { PartitionResponse } from 'unstructured-client/src/sdk/models/operations';
|
|
6
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
|
|
8
|
+
import { Unstructured } from '../index';
|
|
9
|
+
import AutoWithChunkingOutput from './fixtures/table-parse/auto-partition-basic-output.json';
|
|
10
|
+
import AutoWithChunkingRaw from './fixtures/table-parse/auto-partition-basic-raw.json';
|
|
11
|
+
import AutoWithoutChunking from './fixtures/table-parse/auto-partition-raw.json';
|
|
12
|
+
import FastWithoutChunkingRaw from './fixtures/table-parse/fast-partition-raw.json';
|
|
13
|
+
|
|
14
|
+
// Mock the external dependencies
|
|
15
|
+
let UNSTRUCTURED_API_KEY = 'test-api-key';
|
|
16
|
+
|
|
17
|
+
vi.mock('@/config/knowledge', () => ({
|
|
18
|
+
knowledgeEnv: {
|
|
19
|
+
get UNSTRUCTURED_API_KEY() {
|
|
20
|
+
return UNSTRUCTURED_API_KEY;
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
UNSTRUCTURED_SERVER_URL: 'http://test-server.com',
|
|
24
|
+
},
|
|
25
|
+
}));
|
|
26
|
+
|
|
27
|
+
let client: Unstructured;
|
|
28
|
+
|
|
29
|
+
beforeEach(() => {
|
|
30
|
+
client = new Unstructured();
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
afterEach(() => {
|
|
34
|
+
vi.clearAllMocks();
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
const mockPartitionResponse = (elements: any[]) =>
|
|
38
|
+
({
|
|
39
|
+
statusCode: 200,
|
|
40
|
+
elements,
|
|
41
|
+
rawResponse: new Response(),
|
|
42
|
+
contentType: 'application/json',
|
|
43
|
+
}) as PartitionResponse;
|
|
44
|
+
|
|
45
|
+
describe('Unstructured', () => {
|
|
46
|
+
describe('init', () => {
|
|
47
|
+
it('should create an instance with API key from environment', () => {
|
|
48
|
+
expect(client).toBeInstanceOf(Unstructured);
|
|
49
|
+
});
|
|
50
|
+
|
|
51
|
+
it('should create an instance with provided API key', () => {
|
|
52
|
+
const customUnstructured = new Unstructured('custom-api-key');
|
|
53
|
+
expect(customUnstructured).toBeInstanceOf(Unstructured);
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
it('should throw an error if no API key is provided or in environment', () => {
|
|
57
|
+
let defaultKey = UNSTRUCTURED_API_KEY;
|
|
58
|
+
UNSTRUCTURED_API_KEY = '';
|
|
59
|
+
|
|
60
|
+
expect(() => new Unstructured()).toThrow(
|
|
61
|
+
'"UNSTRUCTURED_API_KEY" variables are not set completely, please check your env',
|
|
62
|
+
);
|
|
63
|
+
UNSTRUCTURED_API_KEY = defaultKey;
|
|
64
|
+
});
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
describe('basic partition', () => {
|
|
68
|
+
it('should return empty arrays if partition response is not successful', async () => {
|
|
69
|
+
vi.spyOn(UnstructuredClient.prototype.general, 'partition').mockResolvedValue({
|
|
70
|
+
statusCode: 400,
|
|
71
|
+
} as any);
|
|
72
|
+
|
|
73
|
+
const result = await client.partition({
|
|
74
|
+
fileContent: new Uint8Array(),
|
|
75
|
+
filename: 'test.txt',
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
expect(result.compositeElements).toEqual([]);
|
|
79
|
+
expect(result.originElements).toEqual([]);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
it('should partition content successfully with default strategy', async () => {
|
|
83
|
+
vi.spyOn(UnstructuredClient.prototype.general, 'partition').mockResolvedValue(
|
|
84
|
+
mockPartitionResponse(AutoWithoutChunking),
|
|
85
|
+
);
|
|
86
|
+
|
|
87
|
+
const result = await client.partition({
|
|
88
|
+
fileContent: new Uint8Array(),
|
|
89
|
+
filename: 'test.txt',
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
expect(result.compositeElements).toHaveLength(0);
|
|
93
|
+
expect(result.originElements).toHaveLength(12);
|
|
94
|
+
|
|
95
|
+
expect(result.originElements[0].text).toBe('Multiple Sclerosis Journal 29(6)');
|
|
96
|
+
expect(result.originElements[2].type).toBe('Table');
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it('should partition content successfully with fast strategy', async () => {
|
|
100
|
+
vi.spyOn(UnstructuredClient.prototype.general, 'partition').mockResolvedValue(
|
|
101
|
+
mockPartitionResponse(FastWithoutChunkingRaw),
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
const result = await client.partition({
|
|
105
|
+
fileContent: new Uint8Array(),
|
|
106
|
+
filename: 'test.txt',
|
|
107
|
+
strategy: Strategy.Fast,
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
expect(result.compositeElements).toHaveLength(0);
|
|
111
|
+
expect(result.originElements).toHaveLength(82);
|
|
112
|
+
|
|
113
|
+
expect(result.originElements[0].text).toBe('Multiple Sclerosis Journal 29(6)');
|
|
114
|
+
expect(result.originElements.every((item) => item.text !== 'Table')).toBeTruthy();
|
|
115
|
+
});
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
describe('partition with chunk strategy', () => {
|
|
119
|
+
it('should use provided chunking strategy with Table', async () => {
|
|
120
|
+
vi.spyOn(UnstructuredClient.prototype.general, 'partition').mockResolvedValue(
|
|
121
|
+
mockPartitionResponse(AutoWithChunkingRaw),
|
|
122
|
+
);
|
|
123
|
+
|
|
124
|
+
const result = await client.partition({
|
|
125
|
+
fileContent: new Uint8Array(),
|
|
126
|
+
filename: 'test.txt',
|
|
127
|
+
chunkingStrategy: ChunkingStrategy.Basic,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
expect(result.compositeElements).toHaveLength(6);
|
|
131
|
+
expect(result.originElements).toHaveLength(12);
|
|
132
|
+
|
|
133
|
+
expect(result.originElements).toEqual(AutoWithChunkingOutput.originElements);
|
|
134
|
+
expect(result.originElements).toEqual(AutoWithChunkingOutput.originElements);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
it.skip('should error', async () => {
|
|
138
|
+
vi.spyOn(UnstructuredClient.prototype.general, 'partition').mockResolvedValue(
|
|
139
|
+
mockPartitionResponse([
|
|
140
|
+
{
|
|
141
|
+
type: 'CompositeElement',
|
|
142
|
+
element_id: '32855cf6-5605-4a8e-97a3-3ac0b509b725',
|
|
143
|
+
text: 'abc',
|
|
144
|
+
metadata: {
|
|
145
|
+
filetype: 'application/pdf',
|
|
146
|
+
languages: ['eng'],
|
|
147
|
+
page_number: 1,
|
|
148
|
+
orig_elements: 'e==',
|
|
149
|
+
filename: 'table-parse.pdf',
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
]),
|
|
153
|
+
);
|
|
154
|
+
try {
|
|
155
|
+
await client.partition({
|
|
156
|
+
fileContent: new Uint8Array(),
|
|
157
|
+
filename: 'test.txt',
|
|
158
|
+
chunkingStrategy: ChunkingStrategy.Basic,
|
|
159
|
+
});
|
|
160
|
+
} catch (e) {
|
|
161
|
+
expect(e).toThrowError('unexpected end of file');
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
});
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import zlib from 'node:zlib';
|
|
2
|
+
import pMap from 'p-map';
|
|
3
|
+
import { UnstructuredClient } from 'unstructured-client';
|
|
4
|
+
import { Strategy } from 'unstructured-client/sdk/models/shared';
|
|
5
|
+
import { PartitionResponse } from 'unstructured-client/src/sdk/models/operations';
|
|
6
|
+
|
|
7
|
+
import { knowledgeEnv } from '@/config/knowledge';
|
|
8
|
+
|
|
9
|
+
export enum ChunkingStrategy {
|
|
10
|
+
Basic = 'basic',
|
|
11
|
+
ByPage = 'by_page',
|
|
12
|
+
BySimilarity = 'by_similarity',
|
|
13
|
+
ByTitle = 'by_title',
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UnstructuredPartitionElement {
|
|
17
|
+
compositeId?: string;
|
|
18
|
+
element_id: string;
|
|
19
|
+
metadata: Metadata;
|
|
20
|
+
text: string;
|
|
21
|
+
type: string;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export interface Metadata {
|
|
25
|
+
coordinates: Coordinates;
|
|
26
|
+
filename: string;
|
|
27
|
+
filetype: string;
|
|
28
|
+
image_base64?: string;
|
|
29
|
+
image_mime_type?: string;
|
|
30
|
+
is_continuation?: boolean;
|
|
31
|
+
languages: string[];
|
|
32
|
+
orig_elements?: string;
|
|
33
|
+
page_name?: string;
|
|
34
|
+
page_number: number;
|
|
35
|
+
parent_id?: string;
|
|
36
|
+
text_as_html?: string;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export interface Coordinates {
|
|
40
|
+
layout_height: number;
|
|
41
|
+
layout_width: number;
|
|
42
|
+
points: number[][];
|
|
43
|
+
system: string;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
class UnstructuredError extends Error {
|
|
47
|
+
constructor(message: string) {
|
|
48
|
+
super(message);
|
|
49
|
+
this.name = 'Unstructured';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
interface PartitionParameters {
|
|
54
|
+
chunkingStrategy?: ChunkingStrategy;
|
|
55
|
+
fileContent: Uint8Array;
|
|
56
|
+
filename: string;
|
|
57
|
+
maxCharacters?: number;
|
|
58
|
+
onResponse?: (response: PartitionResponse) => void;
|
|
59
|
+
strategy?: Strategy;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export class Unstructured {
|
|
63
|
+
private client: UnstructuredClient;
|
|
64
|
+
|
|
65
|
+
constructor(apikey?: string) {
|
|
66
|
+
if (!apikey && !knowledgeEnv.UNSTRUCTURED_API_KEY)
|
|
67
|
+
throw new UnstructuredError(
|
|
68
|
+
`"UNSTRUCTURED_API_KEY" variables are not set completely, please check your env`,
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
this.client = new UnstructuredClient({
|
|
72
|
+
security: { apiKeyAuth: apikey || knowledgeEnv.UNSTRUCTURED_API_KEY! },
|
|
73
|
+
serverURL: knowledgeEnv.UNSTRUCTURED_SERVER_URL,
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
async partition(params: PartitionParameters): Promise<{
|
|
78
|
+
compositeElements: UnstructuredPartitionElement[];
|
|
79
|
+
originElements: UnstructuredPartitionElement[];
|
|
80
|
+
}> {
|
|
81
|
+
const hasChunkingStrategy = !!params.chunkingStrategy;
|
|
82
|
+
const response = await this.client.general.partition({
|
|
83
|
+
partitionParameters: {
|
|
84
|
+
chunkingStrategy: params.chunkingStrategy,
|
|
85
|
+
coordinates: true,
|
|
86
|
+
// extractImageBlockTypes: ['Image'],
|
|
87
|
+
files: { content: params.fileContent, fileName: params.filename },
|
|
88
|
+
|
|
89
|
+
includeOrigElements: true,
|
|
90
|
+
maxCharacters: params.maxCharacters || 800,
|
|
91
|
+
strategy: params.strategy,
|
|
92
|
+
uniqueElementIds: true,
|
|
93
|
+
},
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
if (response.statusCode === 200) {
|
|
97
|
+
// after finish partition, we need to filter out some elements
|
|
98
|
+
const elements = response.elements as UnstructuredPartitionElement[];
|
|
99
|
+
|
|
100
|
+
params.onResponse?.(response);
|
|
101
|
+
|
|
102
|
+
let originElements: UnstructuredPartitionElement[] = [];
|
|
103
|
+
let compositeElements: UnstructuredPartitionElement[] = [];
|
|
104
|
+
|
|
105
|
+
if (hasChunkingStrategy) {
|
|
106
|
+
await pMap(elements, async (element) => {
|
|
107
|
+
// Your Base64 encoded string
|
|
108
|
+
const base64EncodedString = element.metadata.orig_elements as string;
|
|
109
|
+
delete element.metadata.orig_elements;
|
|
110
|
+
|
|
111
|
+
if (!base64EncodedString) return;
|
|
112
|
+
|
|
113
|
+
// Step 1: Decode the Base64 encoded string to binary
|
|
114
|
+
const binaryBuffer = Buffer.from(base64EncodedString, 'base64');
|
|
115
|
+
|
|
116
|
+
// Step 2: Decompress the binary data
|
|
117
|
+
const elements = await this.decompressGzip(binaryBuffer);
|
|
118
|
+
|
|
119
|
+
// if element is Table type then get the origin
|
|
120
|
+
if (element.type === 'Table') {
|
|
121
|
+
// skip continuation table due to being split by chunk strategy
|
|
122
|
+
if (element.metadata.is_continuation) {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
compositeElements = [...compositeElements, elements[0]];
|
|
127
|
+
originElements = [...originElements, elements[0]];
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
compositeElements = [...compositeElements, element];
|
|
132
|
+
|
|
133
|
+
originElements = originElements.concat(
|
|
134
|
+
elements.map(
|
|
135
|
+
(e) => ({ ...e, compositeId: element.element_id }) as UnstructuredPartitionElement,
|
|
136
|
+
),
|
|
137
|
+
);
|
|
138
|
+
});
|
|
139
|
+
} else {
|
|
140
|
+
originElements = elements;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
return { compositeElements, originElements };
|
|
144
|
+
} else {
|
|
145
|
+
return { compositeElements: [], originElements: [] };
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
private async decompressGzip(data: Buffer): Promise<UnstructuredPartitionElement[]> {
|
|
150
|
+
return new Promise((resolve, reject) => {
|
|
151
|
+
zlib.inflate(data, (err, decompressedBuffer) => {
|
|
152
|
+
if (err) {
|
|
153
|
+
reject(err);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
// Step 3: Convert the decompressed buffer to a string
|
|
157
|
+
let decompressedString = decompressedBuffer.toString('utf8');
|
|
158
|
+
|
|
159
|
+
// Step 4: Parse the JSON string
|
|
160
|
+
let jsonObject = JSON.parse(decompressedString);
|
|
161
|
+
|
|
162
|
+
resolve(jsonObject);
|
|
163
|
+
});
|
|
164
|
+
});
|
|
165
|
+
}
|
|
166
|
+
}
|
|
@@ -14,6 +14,7 @@ export default {
|
|
|
14
14
|
autoGenerate: '自动补全',
|
|
15
15
|
autoGenerateTooltip: '基于提示词自动补全助手描述',
|
|
16
16
|
autoGenerateTooltipDisabled: '请填写提示词后使用自动补全功能',
|
|
17
|
+
batchDelete: '批量删除',
|
|
17
18
|
blog: '产品博客',
|
|
18
19
|
cancel: '取消',
|
|
19
20
|
changelog: '更新日志',
|
|
@@ -32,6 +33,7 @@ export default {
|
|
|
32
33
|
defaultSession: '自定义助手',
|
|
33
34
|
delete: '删除',
|
|
34
35
|
document: '使用文档',
|
|
36
|
+
download: '下载',
|
|
35
37
|
duplicate: '创建副本',
|
|
36
38
|
edit: '编辑',
|
|
37
39
|
export: '导出配置',
|
|
@@ -185,6 +187,7 @@ export default {
|
|
|
185
187
|
},
|
|
186
188
|
tab: {
|
|
187
189
|
chat: '会话',
|
|
190
|
+
files: '文件',
|
|
188
191
|
market: '发现',
|
|
189
192
|
me: '我',
|
|
190
193
|
setting: '设置',
|
|
@@ -5,6 +5,68 @@ export default {
|
|
|
5
5
|
dragFileTitle: '上传文件',
|
|
6
6
|
dragTitle: '上传图片',
|
|
7
7
|
},
|
|
8
|
+
FileManager: {
|
|
9
|
+
actions: {
|
|
10
|
+
addToKnowledgeBase: '添加到知识库',
|
|
11
|
+
addToOtherKnowledgeBase: '添加到其他知识库',
|
|
12
|
+
batchChunking: '批量分块',
|
|
13
|
+
chunking: '分块',
|
|
14
|
+
chunkingTooltip: '将文件拆分为多个文本块并向量化后,可用于语义检索和文件对话',
|
|
15
|
+
confirmDelete: '即将删除该文件,删除后该将无法找回,请确认你的操作',
|
|
16
|
+
confirmDeleteMultiFiles:
|
|
17
|
+
'即将删除选中的 {{count}} 个文件,删除后该将无法找回,请确认你的操作',
|
|
18
|
+
confirmRemoveFromKnowledgeBase:
|
|
19
|
+
'即将从知识库中移除选中的 {{count}} 个文件,移除后文件仍然可以在全部文件中查看,请确认你的操作',
|
|
20
|
+
copyUrl: '复制链接',
|
|
21
|
+
copyUrlSuccess: '文件地址复制成功',
|
|
22
|
+
createChunkingTask: '准备中...',
|
|
23
|
+
deleteSuccess: '文件删除成功',
|
|
24
|
+
downloading: '文件下载中...',
|
|
25
|
+
removeFromKnowledgeBase: '从知识库中移除',
|
|
26
|
+
removeFromKnowledgeBaseSuccess: '文件移除成功',
|
|
27
|
+
},
|
|
28
|
+
bottom: '已经到底啦',
|
|
29
|
+
config: {
|
|
30
|
+
showFilesInKnowledgeBase: '显示知识库中内容',
|
|
31
|
+
},
|
|
32
|
+
emptyStatus: {
|
|
33
|
+
actions: {
|
|
34
|
+
file: '上传文件',
|
|
35
|
+
folder: '上传文件夹',
|
|
36
|
+
knowledgeBase: '新建知识库',
|
|
37
|
+
},
|
|
38
|
+
or: '或者',
|
|
39
|
+
title: '将文件或文件夹拖到这里',
|
|
40
|
+
},
|
|
41
|
+
title: {
|
|
42
|
+
createdAt: '创建时间',
|
|
43
|
+
size: '大小',
|
|
44
|
+
title: '文件',
|
|
45
|
+
},
|
|
46
|
+
total: {
|
|
47
|
+
fileCount: '共 {{count}} 项',
|
|
48
|
+
selectedCount: '已选 {{count}} 项',
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
FileParsingStatus: {
|
|
52
|
+
chunks: {
|
|
53
|
+
embeddingStatus: {
|
|
54
|
+
empty: '文本块尚未完全向量化,将导致语义检索功能不可用,为提升检索质量,请对文本块向量化',
|
|
55
|
+
processing: '文本块正在向量化,请耐心等待',
|
|
56
|
+
success: '当前文本块均已向量化',
|
|
57
|
+
},
|
|
58
|
+
embeddings: '向量化',
|
|
59
|
+
status: {
|
|
60
|
+
error: '分块失败',
|
|
61
|
+
errorResult: '分块失败,请检查后重试。失败原因:',
|
|
62
|
+
processing: '分块中',
|
|
63
|
+
processingTip: '服务端正在拆分文本块,关闭页面不影响分块进度',
|
|
64
|
+
},
|
|
65
|
+
},
|
|
66
|
+
},
|
|
67
|
+
GoBack: {
|
|
68
|
+
back: '返回',
|
|
69
|
+
},
|
|
8
70
|
ModelSelect: {
|
|
9
71
|
featureTag: {
|
|
10
72
|
custom: '自定义模型,默认设定同时支持函数调用与视觉识别,请根据实际情况验证上述能力的可用性',
|
package/src/store/file/store.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { StateCreator } from 'zustand/vanilla';
|
|
|
4
4
|
|
|
5
5
|
import { createDevtools } from '../middleware/createDevtools';
|
|
6
6
|
import { FilesStoreState, initialState } from './initialState';
|
|
7
|
-
import { FileAction, createFileSlice } from './slices/
|
|
7
|
+
import { FileAction, createFileSlice } from './slices/chat';
|
|
8
8
|
import { TTSFileAction, createTTSFileSlice } from './slices/tts';
|
|
9
9
|
|
|
10
10
|
// =============== 聚合 createStoreFn ============ //
|
|
@@ -5,6 +5,7 @@ import { AsyncLocalStorage } from '@/utils/localStorage';
|
|
|
5
5
|
|
|
6
6
|
export enum SidebarTabKey {
|
|
7
7
|
Chat = 'chat',
|
|
8
|
+
Files = 'files',
|
|
8
9
|
Market = 'market',
|
|
9
10
|
Me = 'me',
|
|
10
11
|
Setting = 'settings',
|
|
@@ -32,12 +33,14 @@ export enum SettingsTabs {
|
|
|
32
33
|
export interface SystemStatus {
|
|
33
34
|
// which sessionGroup should expand
|
|
34
35
|
expandSessionGroupKeys: string[];
|
|
36
|
+
filePanelWidth: number;
|
|
35
37
|
hidePWAInstaller?: boolean;
|
|
36
38
|
inputHeight: number;
|
|
37
39
|
mobileShowPortal?: boolean;
|
|
38
40
|
mobileShowTopic?: boolean;
|
|
39
41
|
sessionsWidth: number;
|
|
40
42
|
showChatSideBar?: boolean;
|
|
43
|
+
showFilePanel?: boolean;
|
|
41
44
|
showSessionPanel?: boolean;
|
|
42
45
|
showSystemRole?: boolean;
|
|
43
46
|
}
|
|
@@ -55,11 +58,13 @@ export interface GlobalState {
|
|
|
55
58
|
|
|
56
59
|
export const INITIAL_STATUS = {
|
|
57
60
|
expandSessionGroupKeys: [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default],
|
|
61
|
+
filePanelWidth: 320,
|
|
58
62
|
hidePWAInstaller: false,
|
|
59
63
|
inputHeight: 200,
|
|
60
64
|
mobileShowTopic: false,
|
|
61
65
|
sessionsWidth: 320,
|
|
62
66
|
showChatSideBar: true,
|
|
67
|
+
showFilePanel: true,
|
|
63
68
|
showSessionPanel: true,
|
|
64
69
|
showSystemRole: false,
|
|
65
70
|
} satisfies SystemStatus;
|
|
@@ -10,12 +10,15 @@ const mobileShowTopic = (s: GlobalStore) => s.status.mobileShowTopic;
|
|
|
10
10
|
const mobileShowPortal = (s: GlobalStore) => s.status.mobileShowPortal;
|
|
11
11
|
const showChatSideBar = (s: GlobalStore) => s.status.showChatSideBar;
|
|
12
12
|
const showSessionPanel = (s: GlobalStore) => s.status.showSessionPanel;
|
|
13
|
+
const showFilePanel = (s: GlobalStore) => s.status.showFilePanel;
|
|
13
14
|
const hidePWAInstaller = (s: GlobalStore) => s.status.hidePWAInstaller;
|
|
14
15
|
|
|
15
16
|
const sessionWidth = (s: GlobalStore) => s.status.sessionsWidth;
|
|
17
|
+
const filePanelWidth = (s: GlobalStore) => s.status.filePanelWidth;
|
|
16
18
|
const inputHeight = (s: GlobalStore) => s.status.inputHeight;
|
|
17
19
|
|
|
18
20
|
export const systemStatusSelectors = {
|
|
21
|
+
filePanelWidth,
|
|
19
22
|
hidePWAInstaller,
|
|
20
23
|
inputHeight,
|
|
21
24
|
mobileShowPortal,
|
|
@@ -23,6 +26,7 @@ export const systemStatusSelectors = {
|
|
|
23
26
|
sessionGroupKeys,
|
|
24
27
|
sessionWidth,
|
|
25
28
|
showChatSideBar,
|
|
29
|
+
showFilePanel,
|
|
26
30
|
showSessionPanel,
|
|
27
31
|
showSystemRole,
|
|
28
32
|
};
|
package/src/types/user/index.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { DeepPartial } from 'utility-types';
|
|
2
|
+
import { z } from 'zod';
|
|
2
3
|
|
|
3
4
|
import { UserSettings } from '@/types/user/settings';
|
|
4
5
|
|
|
@@ -12,17 +13,24 @@ export interface LobeUser {
|
|
|
12
13
|
username?: string | null;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
export
|
|
16
|
+
export const UserGuideSchema = z.object({
|
|
16
17
|
/**
|
|
17
18
|
* Move the settings button to the avatar dropdown
|
|
18
19
|
*/
|
|
19
|
-
moveSettingsToAvatar
|
|
20
|
+
moveSettingsToAvatar: z.boolean().optional(),
|
|
20
21
|
|
|
21
22
|
/**
|
|
22
23
|
* Topic Guide
|
|
23
24
|
*/
|
|
24
|
-
topic
|
|
25
|
-
|
|
25
|
+
topic: z.boolean().optional(),
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* tell user that uploaded files can be found in knowledge base
|
|
29
|
+
*/
|
|
30
|
+
uploadFileInKnowledgeBase: z.boolean().optional(),
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
export type UserGuide = z.infer<typeof UserGuideSchema>;
|
|
26
34
|
|
|
27
35
|
export interface UserPreference {
|
|
28
36
|
guide?: UserGuide;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import chroma from 'chroma-js';
|
|
2
|
+
|
|
3
|
+
export const convertAlphaToSolid = (foreground: string, background: string): string => {
|
|
4
|
+
const fgColor = chroma(foreground);
|
|
5
|
+
const bgColor = chroma(background);
|
|
6
|
+
|
|
7
|
+
const alpha = fgColor.alpha();
|
|
8
|
+
const alphaComplement = 1 - alpha;
|
|
9
|
+
|
|
10
|
+
const mixedColor = [
|
|
11
|
+
fgColor.get('rgb.r') * alpha + bgColor.get('rgb.r') * alphaComplement,
|
|
12
|
+
fgColor.get('rgb.g') * alpha + bgColor.get('rgb.g') * alphaComplement,
|
|
13
|
+
fgColor.get('rgb.b') * alpha + bgColor.get('rgb.b') * alphaComplement,
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
const resultColor = chroma(mixedColor);
|
|
17
|
+
|
|
18
|
+
return resultColor.hex();
|
|
19
|
+
};
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|