@lobehub/chat 1.11.2 → 1.11.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +50 -0
- package/Dockerfile +2 -0
- package/Dockerfile.database +2 -0
- 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/components.json +60 -0
- package/locales/bg-BG/components.json +60 -0
- package/locales/de-DE/components.json +60 -0
- package/locales/en-US/components.json +60 -0
- package/locales/es-ES/components.json +60 -0
- package/locales/fr-FR/components.json +60 -0
- package/locales/it-IT/components.json +60 -0
- package/locales/ja-JP/components.json +60 -0
- package/locales/ko-KR/components.json +60 -0
- package/locales/nl-NL/components.json +60 -0
- package/locales/pl-PL/components.json +60 -0
- package/locales/pt-BR/components.json +60 -0
- package/locales/ru-RU/components.json +60 -0
- package/locales/tr-TR/components.json +60 -0
- package/locales/vi-VN/components.json +60 -0
- package/locales/zh-CN/components.json +60 -0
- package/locales/zh-TW/components.json +60 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/_layout/Desktop/SideBar.tsx +3 -22
- package/src/app/api/chat/agentRuntime.ts +3 -2
- 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/llm.ts +4 -0
- package/src/config/modelProviders/siliconcloud.ts +3 -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/components.ts +62 -0
- package/src/server/globalConfig/index.ts +11 -1
- package/src/utils/colorUtils.ts +19 -0
- package/src/utils/sleep.ts +4 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import { createStyles } from 'antd-style';
|
|
4
|
+
import { CSSProperties, memo } from 'react';
|
|
5
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
|
+
|
|
7
|
+
const useStyles = createStyles(({ token, css }) => ({
|
|
8
|
+
desc: css`
|
|
9
|
+
line-height: 1.4;
|
|
10
|
+
color: ${token.colorTextDescription};
|
|
11
|
+
`,
|
|
12
|
+
header: css`
|
|
13
|
+
padding-block: 24px 0;
|
|
14
|
+
padding-inline: 0.75rem;
|
|
15
|
+
`,
|
|
16
|
+
title: css`
|
|
17
|
+
margin: 0;
|
|
18
|
+
font-size: 26px;
|
|
19
|
+
font-weight: 600;
|
|
20
|
+
line-height: 1.3;
|
|
21
|
+
`,
|
|
22
|
+
}));
|
|
23
|
+
|
|
24
|
+
interface PanelTitleProps {
|
|
25
|
+
desc?: string;
|
|
26
|
+
style?: CSSProperties;
|
|
27
|
+
title?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const PanelTitle = memo(({ title, desc, style }: PanelTitleProps) => {
|
|
31
|
+
const { styles } = useStyles();
|
|
32
|
+
|
|
33
|
+
return (
|
|
34
|
+
<Flexbox className={styles.header} gap={4} style={style}>
|
|
35
|
+
<h1 className={styles.title}>{title}</h1>
|
|
36
|
+
<p className={styles.desc}>{desc}</p>
|
|
37
|
+
</Flexbox>
|
|
38
|
+
);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
export default PanelTitle;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Icon } from '@lobehub/ui';
|
|
2
|
+
import { useTheme } from 'antd-style';
|
|
3
|
+
import { BookTextIcon } from 'lucide-react';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
|
|
6
|
+
interface RepoIconProps {
|
|
7
|
+
size?: number;
|
|
8
|
+
}
|
|
9
|
+
const RepoIcon = memo<RepoIconProps>(({ size = 20 }) => {
|
|
10
|
+
const theme = useTheme();
|
|
11
|
+
|
|
12
|
+
return (
|
|
13
|
+
<Icon
|
|
14
|
+
color={theme.geekblue}
|
|
15
|
+
fill={theme.geekblue3}
|
|
16
|
+
icon={BookTextIcon}
|
|
17
|
+
size={{ fontSize: size }}
|
|
18
|
+
/>
|
|
19
|
+
);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
export default RepoIcon;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { createStyles } from 'antd-style';
|
|
2
|
-
import { type ReactNode, memo } from 'react';
|
|
2
|
+
import { CSSProperties, type ReactNode, memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
5
|
const useStyles = createStyles(({ css }) => ({
|
|
@@ -10,10 +10,11 @@ const useStyles = createStyles(({ css }) => ({
|
|
|
10
10
|
|
|
11
11
|
interface SidebarHeaderProps {
|
|
12
12
|
actions?: ReactNode;
|
|
13
|
+
style?: CSSProperties;
|
|
13
14
|
title: ReactNode;
|
|
14
15
|
}
|
|
15
16
|
|
|
16
|
-
const SidebarHeader = memo<SidebarHeaderProps>(({ title, actions }) => {
|
|
17
|
+
const SidebarHeader = memo<SidebarHeaderProps>(({ title, style, actions }) => {
|
|
17
18
|
const { styles } = useStyles();
|
|
18
19
|
|
|
19
20
|
return (
|
|
@@ -24,6 +25,7 @@ const SidebarHeader = memo<SidebarHeaderProps>(({ title, actions }) => {
|
|
|
24
25
|
horizontal
|
|
25
26
|
padding={14}
|
|
26
27
|
paddingInline={16}
|
|
28
|
+
style={style}
|
|
27
29
|
>
|
|
28
30
|
<Flexbox align={'center'} gap={4} horizontal>
|
|
29
31
|
{title}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
import { ActionIcon } from '@lobehub/ui';
|
|
2
|
+
import { ConfigProvider, Popover, TooltipProps } from 'antd';
|
|
3
|
+
import { createStyles, useTheme } from 'antd-style';
|
|
4
|
+
import { XIcon } from 'lucide-react';
|
|
5
|
+
import { CSSProperties, type FC, type ReactNode } from 'react';
|
|
6
|
+
import { Flexbox } from 'react-layout-kit';
|
|
7
|
+
|
|
8
|
+
const useStyle = createStyles(({ css }) => {
|
|
9
|
+
return {
|
|
10
|
+
close: css`
|
|
11
|
+
color: white;
|
|
12
|
+
`,
|
|
13
|
+
container: css`
|
|
14
|
+
position: relative;
|
|
15
|
+
`,
|
|
16
|
+
footer: css`
|
|
17
|
+
display: flex;
|
|
18
|
+
justify-content: end;
|
|
19
|
+
width: 100%;
|
|
20
|
+
`,
|
|
21
|
+
overlay: css`
|
|
22
|
+
.ant-popover-inner {
|
|
23
|
+
border: none;
|
|
24
|
+
}
|
|
25
|
+
`,
|
|
26
|
+
tip: css`
|
|
27
|
+
position: absolute;
|
|
28
|
+
inset-inline-start: 50%;
|
|
29
|
+
transform: translate(-50%);
|
|
30
|
+
`,
|
|
31
|
+
};
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
export interface TipGuideProps {
|
|
35
|
+
/**
|
|
36
|
+
* 引导内容
|
|
37
|
+
*/
|
|
38
|
+
children?: ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* 类名
|
|
41
|
+
*/
|
|
42
|
+
className?: string;
|
|
43
|
+
/**
|
|
44
|
+
* 默认时候的打开状态
|
|
45
|
+
*/
|
|
46
|
+
defaultOpen?: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* 用于自定义 footer 部分的 render api
|
|
49
|
+
*/
|
|
50
|
+
footerRender?: (dom: ReactNode) => ReactNode;
|
|
51
|
+
/**
|
|
52
|
+
* 最大宽度
|
|
53
|
+
*/
|
|
54
|
+
maxWidth?: number;
|
|
55
|
+
/**
|
|
56
|
+
* 纵向偏移值
|
|
57
|
+
*/
|
|
58
|
+
offsetY?: number;
|
|
59
|
+
/**
|
|
60
|
+
* 当 open 属性变化时候的触发
|
|
61
|
+
*/
|
|
62
|
+
onOpenChange: (open: boolean) => void;
|
|
63
|
+
/**
|
|
64
|
+
* 受控的 open 属性
|
|
65
|
+
*/
|
|
66
|
+
open?: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Tooltip 位置,默认为 bottom
|
|
69
|
+
*/
|
|
70
|
+
placement?: TooltipProps['placement'];
|
|
71
|
+
/**
|
|
72
|
+
* style
|
|
73
|
+
*/
|
|
74
|
+
style?: CSSProperties;
|
|
75
|
+
tip?: boolean;
|
|
76
|
+
/**
|
|
77
|
+
* 引导标题
|
|
78
|
+
*/
|
|
79
|
+
title: string;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const TipGuide: FC<TipGuideProps> = ({
|
|
83
|
+
children,
|
|
84
|
+
placement = 'bottom',
|
|
85
|
+
title,
|
|
86
|
+
offsetY,
|
|
87
|
+
maxWidth = 300,
|
|
88
|
+
className,
|
|
89
|
+
style,
|
|
90
|
+
open,
|
|
91
|
+
onOpenChange: setOpen,
|
|
92
|
+
}) => {
|
|
93
|
+
const token = useTheme();
|
|
94
|
+
const { styles, cx } = useStyle();
|
|
95
|
+
|
|
96
|
+
return (
|
|
97
|
+
<ConfigProvider
|
|
98
|
+
theme={{
|
|
99
|
+
components: {
|
|
100
|
+
Badge: { fontSize: 12, lineHeight: 1 },
|
|
101
|
+
Button: { colorPrimary: token.blue7 },
|
|
102
|
+
Checkbox: {
|
|
103
|
+
colorPrimary: token.blue7,
|
|
104
|
+
colorText: token.colorTextLightSolid,
|
|
105
|
+
},
|
|
106
|
+
Popover: { colorText: token.colorTextLightSolid },
|
|
107
|
+
},
|
|
108
|
+
}}
|
|
109
|
+
>
|
|
110
|
+
{open ? (
|
|
111
|
+
<div className={styles.container}>
|
|
112
|
+
<div
|
|
113
|
+
style={{
|
|
114
|
+
marginTop: offsetY,
|
|
115
|
+
}}
|
|
116
|
+
>
|
|
117
|
+
<Popover
|
|
118
|
+
arrow={{ pointAtCenter: true }}
|
|
119
|
+
color={'blue'}
|
|
120
|
+
content={
|
|
121
|
+
<Flexbox gap={24} horizontal style={{ userSelect: 'none' }}>
|
|
122
|
+
<div>{title}</div>
|
|
123
|
+
<ActionIcon
|
|
124
|
+
className={styles.close}
|
|
125
|
+
icon={XIcon}
|
|
126
|
+
onClick={() => {
|
|
127
|
+
setOpen(false);
|
|
128
|
+
}}
|
|
129
|
+
size={'small'}
|
|
130
|
+
/>
|
|
131
|
+
</Flexbox>
|
|
132
|
+
}
|
|
133
|
+
open={open}
|
|
134
|
+
overlayClassName={cx(className, styles.overlay)}
|
|
135
|
+
overlayStyle={{ maxWidth, zIndex: 1000, ...style }}
|
|
136
|
+
placement={placement}
|
|
137
|
+
trigger="hover"
|
|
138
|
+
>
|
|
139
|
+
{children}
|
|
140
|
+
</Popover>
|
|
141
|
+
</div>
|
|
142
|
+
</div>
|
|
143
|
+
) : (
|
|
144
|
+
children
|
|
145
|
+
)}
|
|
146
|
+
</ConfigProvider>
|
|
147
|
+
);
|
|
148
|
+
};
|
|
149
|
+
|
|
150
|
+
export default TipGuide;
|
package/src/config/llm.ts
CHANGED
|
@@ -90,6 +90,8 @@ export const getLLMConfig = () => {
|
|
|
90
90
|
|
|
91
91
|
ENABLED_SILICONCLOUD: z.boolean(),
|
|
92
92
|
SILICONCLOUD_API_KEY: z.string().optional(),
|
|
93
|
+
SILICONCLOUD_MODEL_LIST: z.string().optional(),
|
|
94
|
+
SILICONCLOUD_PROXY_URL: z.string().optional(),
|
|
93
95
|
},
|
|
94
96
|
runtimeEnv: {
|
|
95
97
|
API_KEY_SELECT_MODE: process.env.API_KEY_SELECT_MODE,
|
|
@@ -177,6 +179,8 @@ export const getLLMConfig = () => {
|
|
|
177
179
|
|
|
178
180
|
ENABLED_SILICONCLOUD: !!process.env.SILICONCLOUD_API_KEY,
|
|
179
181
|
SILICONCLOUD_API_KEY: process.env.SILICONCLOUD_API_KEY,
|
|
182
|
+
SILICONCLOUD_MODEL_LIST: process.env.SILICONCLOUD_MODEL_LIST,
|
|
183
|
+
SILICONCLOUD_PROXY_URL: process.env.SILICONCLOUD_PROXY_URL,
|
|
180
184
|
},
|
|
181
185
|
});
|
|
182
186
|
};
|
|
@@ -122,6 +122,9 @@ const SiliconCloud: ModelProviderCard = {
|
|
|
122
122
|
id: 'siliconcloud',
|
|
123
123
|
modelList: { showModelFetcher: true },
|
|
124
124
|
name: 'SiliconCloud',
|
|
125
|
+
proxyUrl: {
|
|
126
|
+
placeholder: 'https://api.siliconflow.cn/v1',
|
|
127
|
+
},
|
|
125
128
|
};
|
|
126
129
|
|
|
127
130
|
export default SiliconCloud;
|
|
@@ -6,9 +6,14 @@ import { DB_Message, DB_MessageSchema } from '@/database/client/schemas/message'
|
|
|
6
6
|
import { ChatMessage } from '@/types/message';
|
|
7
7
|
import { nanoid } from '@/utils/uuid';
|
|
8
8
|
|
|
9
|
+
/**
|
|
10
|
+
* use `@/types/message` instead
|
|
11
|
+
* @deprecated
|
|
12
|
+
*/
|
|
9
13
|
export interface CreateMessageParams
|
|
10
14
|
extends Partial<Omit<ChatMessage, 'content' | 'role'>>,
|
|
11
15
|
Pick<ChatMessage, 'content' | 'role'> {
|
|
16
|
+
files?: string[];
|
|
12
17
|
fromModel?: string;
|
|
13
18
|
fromProvider?: string;
|
|
14
19
|
sessionId: string;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import { ReactNode, memo } from 'react';
|
|
2
2
|
|
|
3
|
+
import BubblesLoading from '@/components/BubblesLoading';
|
|
3
4
|
import { LOADING_FLAT } from '@/const/message';
|
|
4
5
|
import { ChatMessage } from '@/types/message';
|
|
5
6
|
|
|
6
|
-
import BubblesLoading from '@/components/BubblesLoading';
|
|
7
|
-
|
|
8
7
|
export const DefaultMessage = memo<
|
|
9
8
|
ChatMessage & {
|
|
10
9
|
editableContent: ReactNode;
|
|
@@ -27,6 +27,8 @@ import { LobeTogetherAI } from './togetherai';
|
|
|
27
27
|
import {
|
|
28
28
|
ChatCompetitionOptions,
|
|
29
29
|
ChatStreamPayload,
|
|
30
|
+
EmbeddingsOptions,
|
|
31
|
+
EmbeddingsPayload,
|
|
30
32
|
ModelProvider,
|
|
31
33
|
TextToImagePayload,
|
|
32
34
|
} from './types';
|
|
@@ -78,6 +80,7 @@ class AgentRuntime {
|
|
|
78
80
|
async chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions) {
|
|
79
81
|
return this._runtime.chat(payload, options);
|
|
80
82
|
}
|
|
83
|
+
|
|
81
84
|
async textToImage(payload: TextToImagePayload) {
|
|
82
85
|
return this._runtime.textToImage?.(payload);
|
|
83
86
|
}
|
|
@@ -86,6 +89,10 @@ class AgentRuntime {
|
|
|
86
89
|
return this._runtime.models?.();
|
|
87
90
|
}
|
|
88
91
|
|
|
92
|
+
async embeddings(payload: EmbeddingsPayload, options?: EmbeddingsOptions) {
|
|
93
|
+
return this._runtime.embeddings?.(payload, options);
|
|
94
|
+
}
|
|
95
|
+
|
|
89
96
|
/**
|
|
90
97
|
* @description Initialize the runtime with the provider and the options
|
|
91
98
|
* @param provider choose a model provider
|
|
@@ -247,12 +254,12 @@ class AgentRuntime {
|
|
|
247
254
|
|
|
248
255
|
case ModelProvider.Ai360: {
|
|
249
256
|
runtimeModel = new LobeAi360AI(params.ai360 ?? {});
|
|
250
|
-
break
|
|
257
|
+
break;
|
|
251
258
|
}
|
|
252
259
|
|
|
253
260
|
case ModelProvider.SiliconCloud: {
|
|
254
261
|
runtimeModel = new LobeSiliconCloudAI(params.siliconcloud ?? {});
|
|
255
|
-
break
|
|
262
|
+
break;
|
|
256
263
|
}
|
|
257
264
|
}
|
|
258
265
|
|
|
@@ -3,12 +3,20 @@ import OpenAI from 'openai';
|
|
|
3
3
|
import { TextToImagePayload } from '@/libs/agent-runtime/types/textToImage';
|
|
4
4
|
import { ChatModelCard } from '@/types/llm';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import {
|
|
7
|
+
ChatCompetitionOptions,
|
|
8
|
+
ChatStreamPayload,
|
|
9
|
+
EmbeddingItem,
|
|
10
|
+
EmbeddingsOptions,
|
|
11
|
+
EmbeddingsPayload,
|
|
12
|
+
} from './types';
|
|
7
13
|
|
|
8
14
|
export interface LobeRuntimeAI {
|
|
9
15
|
baseURL?: string;
|
|
10
16
|
chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions): Promise<Response>;
|
|
11
17
|
|
|
18
|
+
embeddings?(payload: EmbeddingsPayload, options?: EmbeddingsOptions): Promise<EmbeddingItem[]>;
|
|
19
|
+
|
|
12
20
|
models?(): Promise<any>;
|
|
13
21
|
|
|
14
22
|
textToImage?: (payload: TextToImagePayload) => Promise<string[]>;
|
|
@@ -21,4 +29,9 @@ export abstract class LobeOpenAICompatibleRuntime {
|
|
|
21
29
|
abstract chat(payload: ChatStreamPayload, options?: ChatCompetitionOptions): Promise<Response>;
|
|
22
30
|
|
|
23
31
|
abstract models(): Promise<ChatModelCard[]>;
|
|
32
|
+
|
|
33
|
+
abstract embeddings(
|
|
34
|
+
payload: EmbeddingsPayload,
|
|
35
|
+
options?: EmbeddingsOptions,
|
|
36
|
+
): Promise<EmbeddingItem[]>;
|
|
24
37
|
}
|
|
@@ -3,7 +3,7 @@ import OpenAI, { ClientOptions } from 'openai';
|
|
|
3
3
|
|
|
4
4
|
import Qwen from '@/config/modelProviders/qwen';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { LobeRuntimeAI } from '../BaseAI';
|
|
7
7
|
import { AgentRuntimeErrorType } from '../error';
|
|
8
8
|
import { ChatCompetitionOptions, ChatStreamPayload, ModelProvider } from '../types';
|
|
9
9
|
import { AgentRuntimeError } from '../utils/createError';
|
|
@@ -23,7 +23,7 @@ const DEFAULT_BASE_URL = 'https://dashscope.aliyuncs.com/compatible-mode/v1';
|
|
|
23
23
|
* or
|
|
24
24
|
* 2. Set S3-* enviroment variables properly to store all uploaded files.
|
|
25
25
|
*/
|
|
26
|
-
export class LobeQwenAI
|
|
26
|
+
export class LobeQwenAI implements LobeRuntimeAI {
|
|
27
27
|
client: OpenAI;
|
|
28
28
|
baseURL: string;
|
|
29
29
|
|
|
@@ -32,7 +32,6 @@ export class LobeQwenAI extends LobeOpenAICompatibleRuntime implements LobeRunti
|
|
|
32
32
|
baseURL = DEFAULT_BASE_URL,
|
|
33
33
|
...res
|
|
34
34
|
}: ClientOptions & Record<string, any> = {}) {
|
|
35
|
-
super();
|
|
36
35
|
if (!apiKey) throw AgentRuntimeError.createError(AgentRuntimeErrorType.InvalidProviderAPIKey);
|
|
37
36
|
this.client = new OpenAI({ apiKey, baseURL, ...res });
|
|
38
37
|
this.baseURL = this.client.baseURL;
|
|
@@ -108,7 +107,7 @@ export class LobeQwenAI extends LobeOpenAICompatibleRuntime implements LobeRunti
|
|
|
108
107
|
...payload,
|
|
109
108
|
messages,
|
|
110
109
|
result_format: 'message',
|
|
111
|
-
stream: !!tools?.length ? false : stream ?? true,
|
|
110
|
+
stream: !!tools?.length ? false : (stream ?? true),
|
|
112
111
|
top_p: top_p && top_p >= 1 ? 0.999 : top_p,
|
|
113
112
|
};
|
|
114
113
|
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
export interface EmbeddingsPayload {
|
|
2
|
+
/**
|
|
3
|
+
* The number of dimensions the resulting output embeddings should have. Only
|
|
4
|
+
* supported in `text-embedding-3` and later models.
|
|
5
|
+
*/
|
|
6
|
+
dimensions?: number;
|
|
7
|
+
/**
|
|
8
|
+
* Input text to embed, encoded as a string or array of tokens. To embed multiple
|
|
9
|
+
* inputs in a single request, pass an array of strings .
|
|
10
|
+
* The input must not exceed the max input tokens for the model (8192 tokens for
|
|
11
|
+
* `text-embedding-ada-002`), cannot be an empty string, and any array must be 2048
|
|
12
|
+
* dimensions or less.
|
|
13
|
+
*/
|
|
14
|
+
input: string | Array<string>;
|
|
15
|
+
|
|
16
|
+
model: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export interface EmbeddingsOptions {
|
|
20
|
+
headers?: Record<string, any>;
|
|
21
|
+
signal?: AbortSignal;
|
|
22
|
+
/**
|
|
23
|
+
* userId for the embeddings
|
|
24
|
+
*/
|
|
25
|
+
user?: string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface EmbeddingItem {
|
|
29
|
+
/**
|
|
30
|
+
* The embedding vector, which is a list of floats. The length of vector depends on
|
|
31
|
+
* the model as listed in the
|
|
32
|
+
* [embedding guide](https://platform.openai.com/docs/guides/embeddings).
|
|
33
|
+
*/
|
|
34
|
+
embedding: Array<number>;
|
|
35
|
+
/**
|
|
36
|
+
* The index of the embedding in the list of embeddings.
|
|
37
|
+
*/
|
|
38
|
+
index: number;
|
|
39
|
+
/**
|
|
40
|
+
* The object type, which is always "embedding".
|
|
41
|
+
*/
|
|
42
|
+
object: 'embedding';
|
|
43
|
+
}
|
|
@@ -6,7 +6,14 @@ import { ChatModelCard } from '@/types/llm';
|
|
|
6
6
|
|
|
7
7
|
import { LobeRuntimeAI } from '../../BaseAI';
|
|
8
8
|
import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '../../error';
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
ChatCompetitionOptions,
|
|
11
|
+
ChatCompletionErrorPayload,
|
|
12
|
+
ChatStreamPayload,
|
|
13
|
+
EmbeddingItem,
|
|
14
|
+
EmbeddingsOptions,
|
|
15
|
+
EmbeddingsPayload,
|
|
16
|
+
} from '../../types';
|
|
10
17
|
import { AgentRuntimeError } from '../createError';
|
|
11
18
|
import { debugResponse, debugStream } from '../debugStream';
|
|
12
19
|
import { desensitizeUrl } from '../desensitizeUrl';
|
|
@@ -154,7 +161,7 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
|
154
161
|
const response = await this.client.chat.completions.create(
|
|
155
162
|
{
|
|
156
163
|
...postPayload,
|
|
157
|
-
...(chatCompletion?.noUserId ? {} : { user: options?.user })
|
|
164
|
+
...(chatCompletion?.noUserId ? {} : { user: options?.user }),
|
|
158
165
|
},
|
|
159
166
|
{
|
|
160
167
|
// https://github.com/lobehub/lobe-chat/pull/318
|
|
@@ -215,6 +222,22 @@ export const LobeOpenAICompatibleFactory = <T extends Record<string, any> = any>
|
|
|
215
222
|
.filter(Boolean) as ChatModelCard[];
|
|
216
223
|
}
|
|
217
224
|
|
|
225
|
+
async embeddings(
|
|
226
|
+
payload: EmbeddingsPayload,
|
|
227
|
+
options?: EmbeddingsOptions,
|
|
228
|
+
): Promise<EmbeddingItem[]> {
|
|
229
|
+
try {
|
|
230
|
+
const res = await this.client.embeddings.create(
|
|
231
|
+
{ ...payload, user: options?.user },
|
|
232
|
+
{ headers: options?.headers, signal: options?.signal },
|
|
233
|
+
);
|
|
234
|
+
|
|
235
|
+
return res.data;
|
|
236
|
+
} catch (error) {
|
|
237
|
+
throw this.handleError(error);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
218
241
|
async textToImage(payload: TextToImagePayload) {
|
|
219
242
|
try {
|
|
220
243
|
const res = await this.client.images.generate(payload);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export const LANGCHAIN_SUPPORT_TEXT_LIST = [
|
|
2
|
+
'txt',
|
|
3
|
+
'md',
|
|
4
|
+
'markdown',
|
|
5
|
+
'md',
|
|
6
|
+
'mdx',
|
|
7
|
+
'toml',
|
|
8
|
+
'yaml',
|
|
9
|
+
'json',
|
|
10
|
+
|
|
11
|
+
'sh',
|
|
12
|
+
'patch',
|
|
13
|
+
// js
|
|
14
|
+
'js',
|
|
15
|
+
'jsx',
|
|
16
|
+
'mjs',
|
|
17
|
+
'tsx',
|
|
18
|
+
'ts',
|
|
19
|
+
'less',
|
|
20
|
+
'css',
|
|
21
|
+
// rust
|
|
22
|
+
'rs',
|
|
23
|
+
// python
|
|
24
|
+
'py',
|
|
25
|
+
'java',
|
|
26
|
+
// database
|
|
27
|
+
'sql',
|
|
28
|
+
'db',
|
|
29
|
+
];
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './loaders';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
// @vitest-environment node
|
|
2
|
+
import * as fs from 'node:fs';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
|
|
5
|
+
import { CodeLoader } from '../index';
|
|
6
|
+
import longResult from './long.json';
|
|
7
|
+
|
|
8
|
+
describe('CodeLoader', () => {
|
|
9
|
+
it('split simple code', async () => {
|
|
10
|
+
const jsCode = `function helloWorld() {
|
|
11
|
+
console.log("Hello, World!");
|
|
12
|
+
}
|
|
13
|
+
// Call the function
|
|
14
|
+
helloWorld();`;
|
|
15
|
+
|
|
16
|
+
const result = await CodeLoader(jsCode, 'js');
|
|
17
|
+
|
|
18
|
+
expect(result).toEqual([
|
|
19
|
+
{
|
|
20
|
+
pageContent:
|
|
21
|
+
'function helloWorld() {\n console.log("Hello, World!");\n}\n// Call the function\nhelloWorld();',
|
|
22
|
+
metadata: { loc: { lines: { from: 1, to: 5 } } },
|
|
23
|
+
},
|
|
24
|
+
]);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('split long', async () => {
|
|
28
|
+
const code = fs.readFileSync(join(__dirname, `./long.txt`), 'utf-8');
|
|
29
|
+
|
|
30
|
+
const result = await CodeLoader(code, 'js');
|
|
31
|
+
|
|
32
|
+
expect(result).toEqual(longResult);
|
|
33
|
+
});
|
|
34
|
+
});
|