@lobehub/chat 1.47.5 → 1.47.7
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/changelog/v1.json +18 -0
- package/package.json +1 -1
- package/src/app/(main)/settings/provider/(detail)/[id]/index.tsx +8 -2
- package/src/app/(main)/settings/provider/(list)/ProviderGrid/Card.tsx +6 -50
- package/src/app/(main)/settings/provider/(list)/ProviderGrid/style.ts +50 -0
- package/src/services/__tests__/_auth.test.ts +24 -0
- package/src/services/_auth.ts +16 -2
- package/src/services/chat.ts +8 -73
- package/src/types/llm.ts +4 -2
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,56 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.47.7](https://github.com/lobehub/lobe-chat/compare/v1.47.6...v1.47.7)
|
6
|
+
|
7
|
+
<sup>Released on **2025-01-20**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Remove redundant payload remapping in client-fetch.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Remove redundant payload remapping in client-fetch, closes [#5267](https://github.com/lobehub/lobe-chat/issues/5267) ([0c7dd82](https://github.com/lobehub/lobe-chat/commit/0c7dd82))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.47.6](https://github.com/lobehub/lobe-chat/compare/v1.47.5...v1.47.6)
|
31
|
+
|
32
|
+
<sup>Released on **2025-01-20**</sup>
|
33
|
+
|
34
|
+
#### ♻ Code Refactoring
|
35
|
+
|
36
|
+
- **misc**: Refactor provider code.
|
37
|
+
|
38
|
+
<br/>
|
39
|
+
|
40
|
+
<details>
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
42
|
+
|
43
|
+
#### Code refactoring
|
44
|
+
|
45
|
+
- **misc**: Refactor provider code, closes [#5516](https://github.com/lobehub/lobe-chat/issues/5516) ([fa1a07f](https://github.com/lobehub/lobe-chat/commit/fa1a07f))
|
46
|
+
|
47
|
+
</details>
|
48
|
+
|
49
|
+
<div align="right">
|
50
|
+
|
51
|
+
[](#readme-top)
|
52
|
+
|
53
|
+
</div>
|
54
|
+
|
5
55
|
### [Version 1.47.5](https://github.com/lobehub/lobe-chat/compare/v1.47.4...v1.47.5)
|
6
56
|
|
7
57
|
<sup>Released on **2025-01-20**</sup>
|
package/changelog/v1.json
CHANGED
@@ -1,4 +1,22 @@
|
|
1
1
|
[
|
2
|
+
{
|
3
|
+
"children": {
|
4
|
+
"improvements": [
|
5
|
+
"Remove redundant payload remapping in client-fetch."
|
6
|
+
]
|
7
|
+
},
|
8
|
+
"date": "2025-01-20",
|
9
|
+
"version": "1.47.7"
|
10
|
+
},
|
11
|
+
{
|
12
|
+
"children": {
|
13
|
+
"improvements": [
|
14
|
+
"Refactor provider code."
|
15
|
+
]
|
16
|
+
},
|
17
|
+
"date": "2025-01-20",
|
18
|
+
"version": "1.47.6"
|
19
|
+
},
|
2
20
|
{
|
3
21
|
"children": {
|
4
22
|
"improvements": [
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.47.
|
3
|
+
"version": "1.47.7",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot 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",
|
@@ -6,10 +6,16 @@ import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
import ModelList from '../../features/ModelList';
|
7
7
|
import ProviderConfig, { ProviderConfigProps } from '../../features/ProviderConfig';
|
8
8
|
|
9
|
-
|
9
|
+
interface ProviderDetailProps extends ProviderConfigProps {
|
10
|
+
showConfig?: boolean;
|
11
|
+
}
|
12
|
+
const ProviderDetail = memo<ProviderDetailProps>(({ showConfig = true, ...card }) => {
|
10
13
|
return (
|
11
14
|
<Flexbox gap={24} paddingBlock={8}>
|
12
|
-
|
15
|
+
{/* ↓ cloud slot ↓ */}
|
16
|
+
|
17
|
+
{/* ↑ cloud slot ↑ */}
|
18
|
+
{showConfig && <ProviderConfig {...card} />}
|
13
19
|
<ModelList id={card.id} />
|
14
20
|
</Flexbox>
|
15
21
|
);
|
@@ -1,7 +1,6 @@
|
|
1
1
|
import { ProviderCombine, ProviderIcon } from '@lobehub/icons';
|
2
2
|
import { Avatar } from '@lobehub/ui';
|
3
3
|
import { Divider, Skeleton, Typography } from 'antd';
|
4
|
-
import { createStyles } from 'antd-style';
|
5
4
|
import Link from 'next/link';
|
6
5
|
import { memo } from 'react';
|
7
6
|
import { useTranslation } from 'react-i18next';
|
@@ -11,56 +10,9 @@ import InstantSwitch from '@/components/InstantSwitch';
|
|
11
10
|
import { useAiInfraStore } from '@/store/aiInfra';
|
12
11
|
import { AiProviderListItem } from '@/types/aiProvider';
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
17
|
-
banner: css`
|
18
|
-
opacity: ${isDarkMode ? 0.9 : 0.4};
|
19
|
-
`,
|
20
|
-
container: css`
|
21
|
-
position: relative;
|
22
|
-
|
23
|
-
overflow: hidden;
|
24
|
-
|
25
|
-
height: 100%;
|
26
|
-
border-radius: 12px;
|
27
|
-
|
28
|
-
background: ${token.colorBgContainer};
|
29
|
-
box-shadow: 0 0 1px 1px ${isDarkMode ? token.colorFillQuaternary : token.colorFillSecondary}
|
30
|
-
inset;
|
13
|
+
import { useStyles } from './style';
|
31
14
|
|
32
|
-
|
33
|
-
|
34
|
-
&:hover {
|
35
|
-
box-shadow: 0 0 1px 1px ${isDarkMode ? token.colorFillSecondary : token.colorFill} inset;
|
36
|
-
}
|
37
|
-
`,
|
38
|
-
desc: css`
|
39
|
-
min-height: 44px;
|
40
|
-
margin-block-end: 0 !important;
|
41
|
-
color: ${token.colorTextDescription};
|
42
|
-
`,
|
43
|
-
tagBlue: css`
|
44
|
-
color: ${token.geekblue};
|
45
|
-
background: ${token.geekblue1};
|
46
|
-
`,
|
47
|
-
tagGreen: css`
|
48
|
-
color: ${token.green};
|
49
|
-
background: ${token.green1};
|
50
|
-
`,
|
51
|
-
time: css`
|
52
|
-
color: ${token.colorTextDescription};
|
53
|
-
`,
|
54
|
-
title: css`
|
55
|
-
zoom: 1.2;
|
56
|
-
margin-block-end: 0 !important;
|
57
|
-
font-size: 18px !important;
|
58
|
-
font-weight: bold;
|
59
|
-
`,
|
60
|
-
token: css`
|
61
|
-
font-family: ${token.fontFamilyCode};
|
62
|
-
`,
|
63
|
-
}));
|
15
|
+
const { Paragraph } = Typography;
|
64
16
|
|
65
17
|
interface ProviderCardProps extends AiProviderListItem {
|
66
18
|
loading?: boolean;
|
@@ -78,6 +30,10 @@ const ProviderCard = memo<ProviderCardProps>(
|
|
78
30
|
</Flexbox>
|
79
31
|
);
|
80
32
|
|
33
|
+
/* ↓ cloud slot ↓ */
|
34
|
+
|
35
|
+
/* ↑ cloud slot ↑ */
|
36
|
+
|
81
37
|
return (
|
82
38
|
<Flexbox className={cx(styles.container)} gap={24}>
|
83
39
|
<Flexbox gap={12} padding={16} width={'100%'}>
|
@@ -0,0 +1,50 @@
|
|
1
|
+
import { createStyles } from 'antd-style';
|
2
|
+
|
3
|
+
export const useStyles = createStyles(({ css, token, isDarkMode }) => ({
|
4
|
+
banner: css`
|
5
|
+
opacity: ${isDarkMode ? 0.9 : 0.4};
|
6
|
+
`,
|
7
|
+
container: css`
|
8
|
+
position: relative;
|
9
|
+
|
10
|
+
overflow: hidden;
|
11
|
+
|
12
|
+
height: 100%;
|
13
|
+
border-radius: 12px;
|
14
|
+
|
15
|
+
background: ${token.colorBgContainer};
|
16
|
+
box-shadow: 0 0 1px 1px ${isDarkMode ? token.colorFillQuaternary : token.colorFillSecondary}
|
17
|
+
inset;
|
18
|
+
|
19
|
+
transition: box-shadow 0.2s ${token.motionEaseInOut};
|
20
|
+
|
21
|
+
&:hover {
|
22
|
+
box-shadow: 0 0 1px 1px ${isDarkMode ? token.colorFillSecondary : token.colorFill} inset;
|
23
|
+
}
|
24
|
+
`,
|
25
|
+
desc: css`
|
26
|
+
min-height: 44px;
|
27
|
+
margin-block-end: 0 !important;
|
28
|
+
color: ${token.colorTextDescription};
|
29
|
+
`,
|
30
|
+
tagBlue: css`
|
31
|
+
color: ${token.geekblue};
|
32
|
+
background: ${token.geekblue1};
|
33
|
+
`,
|
34
|
+
tagGreen: css`
|
35
|
+
color: ${token.green};
|
36
|
+
background: ${token.green1};
|
37
|
+
`,
|
38
|
+
time: css`
|
39
|
+
color: ${token.colorTextDescription};
|
40
|
+
`,
|
41
|
+
title: css`
|
42
|
+
zoom: 1.2;
|
43
|
+
margin-block-end: 0 !important;
|
44
|
+
font-size: 18px !important;
|
45
|
+
font-weight: bold;
|
46
|
+
`,
|
47
|
+
token: css`
|
48
|
+
font-family: ${token.fontFamilyCode};
|
49
|
+
`,
|
50
|
+
}));
|
@@ -92,6 +92,11 @@ describe('getProviderAuthPayload', () => {
|
|
92
92
|
awsAccessKeyId: mockBedrockConfig.accessKeyId,
|
93
93
|
awsRegion: mockBedrockConfig.region,
|
94
94
|
awsSecretAccessKey: mockBedrockConfig.secretAccessKey,
|
95
|
+
accessKeyId: mockBedrockConfig.accessKeyId,
|
96
|
+
accessKeySecret: mockBedrockConfig.secretAccessKey,
|
97
|
+
awsSessionToken: undefined,
|
98
|
+
region: mockBedrockConfig.region,
|
99
|
+
sessionToken: undefined,
|
95
100
|
});
|
96
101
|
});
|
97
102
|
|
@@ -107,6 +112,7 @@ describe('getProviderAuthPayload', () => {
|
|
107
112
|
expect(payload).toEqual({
|
108
113
|
apiKey: mockAzureConfig.apiKey,
|
109
114
|
azureApiVersion: mockAzureConfig.apiVersion,
|
115
|
+
apiVersion: mockAzureConfig.apiVersion,
|
110
116
|
baseURL: mockAzureConfig.endpoint,
|
111
117
|
});
|
112
118
|
});
|
@@ -151,6 +157,24 @@ describe('getProviderAuthPayload', () => {
|
|
151
157
|
});
|
152
158
|
});
|
153
159
|
|
160
|
+
it('should return correct payload for Cloudflare provider', () => {
|
161
|
+
// 假设的 Cloudflare 配置
|
162
|
+
const mockCloudflareConfig = {
|
163
|
+
apiKey: 'cloudflare-api-key',
|
164
|
+
baseURLOrAccountID: 'cloudflare-base-url-or-account-id',
|
165
|
+
};
|
166
|
+
act(() => {
|
167
|
+
setModelProviderConfig('cloudflare', mockCloudflareConfig);
|
168
|
+
});
|
169
|
+
|
170
|
+
const payload = getProviderAuthPayload(ModelProvider.Cloudflare, mockCloudflareConfig);
|
171
|
+
expect(payload).toEqual({
|
172
|
+
apiKey: mockCloudflareConfig.apiKey,
|
173
|
+
baseURLOrAccountID: mockCloudflareConfig.baseURLOrAccountID,
|
174
|
+
cloudflareBaseURLOrAccountID: mockCloudflareConfig.baseURLOrAccountID,
|
175
|
+
});
|
176
|
+
});
|
177
|
+
|
154
178
|
it('should return an empty object or throw an error for an unknown provider', () => {
|
155
179
|
const payload = getProviderAuthPayload('UnknownProvider', {});
|
156
180
|
expect(payload).toEqual({});
|
package/src/services/_auth.ts
CHANGED
@@ -31,11 +31,19 @@ export const getProviderAuthPayload = (
|
|
31
31
|
const apiKey = (awsSecretAccessKey || '') + (awsAccessKeyId || '');
|
32
32
|
|
33
33
|
return {
|
34
|
+
accessKeyId,
|
35
|
+
accessKeySecret: awsSecretAccessKey,
|
34
36
|
apiKey,
|
37
|
+
/** @deprecated */
|
35
38
|
awsAccessKeyId,
|
39
|
+
/** @deprecated */
|
36
40
|
awsRegion: region,
|
41
|
+
/** @deprecated */
|
37
42
|
awsSecretAccessKey,
|
43
|
+
/** @deprecated */
|
38
44
|
awsSessionToken: sessionToken,
|
45
|
+
region,
|
46
|
+
sessionToken,
|
39
47
|
};
|
40
48
|
}
|
41
49
|
|
@@ -54,7 +62,10 @@ export const getProviderAuthPayload = (
|
|
54
62
|
case ModelProvider.Azure: {
|
55
63
|
return {
|
56
64
|
apiKey: keyVaults.apiKey,
|
57
|
-
|
65
|
+
|
66
|
+
apiVersion: keyVaults.apiVersion,
|
67
|
+
/** @deprecated */
|
68
|
+
azureApiVersion: keyVaults.apiVersion,
|
58
69
|
baseURL: keyVaults.baseURL || keyVaults.endpoint,
|
59
70
|
};
|
60
71
|
}
|
@@ -66,7 +77,10 @@ export const getProviderAuthPayload = (
|
|
66
77
|
case ModelProvider.Cloudflare: {
|
67
78
|
return {
|
68
79
|
apiKey: keyVaults?.apiKey,
|
69
|
-
|
80
|
+
|
81
|
+
baseURLOrAccountID: keyVaults?.baseURLOrAccountID,
|
82
|
+
/** @deprecated */
|
83
|
+
cloudflareBaseURLOrAccountID: keyVaults?.baseURLOrAccountID,
|
70
84
|
};
|
71
85
|
}
|
72
86
|
|
package/src/services/chat.ts
CHANGED
@@ -124,90 +124,25 @@ interface CreateAssistantMessageStream extends FetchSSEOptions {
|
|
124
124
|
* **Note**: if you try to fetch directly, use `fetchOnClient` instead.
|
125
125
|
*/
|
126
126
|
export function initializeWithClientStore(provider: string, payload: any) {
|
127
|
-
|
127
|
+
/**
|
128
|
+
* Since #5267, we map parameters for client-fetch in function `getProviderAuthPayload`
|
129
|
+
* which called by `createPayloadWithKeyVaults` below.
|
130
|
+
* @see https://github.com/lobehub/lobe-chat/pull/5267
|
131
|
+
* @file src/services/_auth.ts
|
132
|
+
*/
|
128
133
|
const providerAuthPayload = { ...payload, ...createPayloadWithKeyVaults(provider) };
|
129
134
|
const commonOptions = {
|
130
|
-
//
|
135
|
+
// Allow OpenAI SDK and Anthropic SDK run on browser
|
131
136
|
dangerouslyAllowBrowser: true,
|
132
137
|
};
|
133
|
-
let providerOptions = {};
|
134
|
-
|
135
|
-
switch (provider) {
|
136
|
-
default:
|
137
|
-
case ModelProvider.OpenAI: {
|
138
|
-
providerOptions = {
|
139
|
-
baseURL: providerAuthPayload?.baseURL,
|
140
|
-
};
|
141
|
-
break;
|
142
|
-
}
|
143
|
-
case ModelProvider.Azure: {
|
144
|
-
providerOptions = {
|
145
|
-
apiKey: providerAuthPayload?.apiKey,
|
146
|
-
apiVersion: providerAuthPayload?.azureApiVersion,
|
147
|
-
};
|
148
|
-
break;
|
149
|
-
}
|
150
|
-
case ModelProvider.Google: {
|
151
|
-
providerOptions = {
|
152
|
-
baseURL: providerAuthPayload?.baseURL,
|
153
|
-
};
|
154
|
-
break;
|
155
|
-
}
|
156
|
-
case ModelProvider.Bedrock: {
|
157
|
-
if (providerAuthPayload?.apiKey) {
|
158
|
-
providerOptions = {
|
159
|
-
accessKeyId: providerAuthPayload?.awsAccessKeyId,
|
160
|
-
accessKeySecret: providerAuthPayload?.awsSecretAccessKey,
|
161
|
-
region: providerAuthPayload?.awsRegion,
|
162
|
-
sessionToken: providerAuthPayload?.awsSessionToken,
|
163
|
-
};
|
164
|
-
}
|
165
|
-
break;
|
166
|
-
}
|
167
|
-
case ModelProvider.Ollama: {
|
168
|
-
providerOptions = {
|
169
|
-
baseURL: providerAuthPayload?.baseURL,
|
170
|
-
};
|
171
|
-
break;
|
172
|
-
}
|
173
|
-
case ModelProvider.Perplexity: {
|
174
|
-
providerOptions = {
|
175
|
-
apikey: providerAuthPayload?.apiKey,
|
176
|
-
baseURL: providerAuthPayload?.baseURL,
|
177
|
-
};
|
178
|
-
break;
|
179
|
-
}
|
180
|
-
case ModelProvider.Anthropic: {
|
181
|
-
providerOptions = {
|
182
|
-
baseURL: providerAuthPayload?.baseURL,
|
183
|
-
};
|
184
|
-
break;
|
185
|
-
}
|
186
|
-
case ModelProvider.Groq: {
|
187
|
-
providerOptions = {
|
188
|
-
apikey: providerAuthPayload?.apiKey,
|
189
|
-
baseURL: providerAuthPayload?.baseURL,
|
190
|
-
};
|
191
|
-
break;
|
192
|
-
}
|
193
|
-
case ModelProvider.Cloudflare: {
|
194
|
-
providerOptions = {
|
195
|
-
apikey: providerAuthPayload?.apiKey,
|
196
|
-
baseURLOrAccountID: providerAuthPayload?.cloudflareBaseURLOrAccountID,
|
197
|
-
};
|
198
|
-
break;
|
199
|
-
}
|
200
|
-
}
|
201
|
-
|
202
138
|
/**
|
203
139
|
* Configuration override order:
|
204
|
-
* payload ->
|
140
|
+
* payload -> providerAuthPayload -> commonOptions
|
205
141
|
*/
|
206
142
|
return AgentRuntime.initializeWithProviderOptions(provider, {
|
207
143
|
[provider]: {
|
208
144
|
...commonOptions,
|
209
145
|
...providerAuthPayload,
|
210
|
-
...providerOptions,
|
211
146
|
...payload,
|
212
147
|
},
|
213
148
|
});
|
package/src/types/llm.ts
CHANGED
@@ -119,13 +119,15 @@ export interface ModelProviderCard {
|
|
119
119
|
* @deprecated
|
120
120
|
*/
|
121
121
|
showApiKey?: boolean;
|
122
|
-
|
123
122
|
/**
|
124
123
|
* whether show checker in the provider config
|
125
124
|
* @deprecated
|
126
125
|
*/
|
127
126
|
showChecker?: boolean;
|
128
|
-
|
127
|
+
/**
|
128
|
+
* whether to show the provider config
|
129
|
+
*/
|
130
|
+
showConfig?: boolean;
|
129
131
|
/**
|
130
132
|
* whether to smoothing the output
|
131
133
|
* @deprecated
|