@lobehub/chat 1.15.19 → 1.15.21
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.
Potentially problematic release.
This version of @lobehub/chat might be problematic. Click here for more details.
- package/CHANGELOG.md +42 -0
- package/docker-compose/production/.env.example +1 -1
- package/docker-compose/production/.env.zh-CN.example +1 -1
- package/docs/self-hosting/server-database/docker-compose.mdx +1 -1
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +1 -1
- package/package.json +1 -1
- package/src/const/settings/agent.ts +1 -1
- package/src/database/client/schemas/session.ts +1 -1
- package/src/features/AgentSetting/AgentModal/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Temperature.tsx +1 -1
- package/src/features/Conversation/components/VirtualizedList/index.tsx +1 -1
- package/src/libs/agent-runtime/anthropic/index.test.ts +2 -2
- package/src/libs/agent-runtime/anthropic/index.ts +4 -1
- package/src/libs/agent-runtime/bedrock/index.test.ts +2 -2
- package/src/libs/agent-runtime/bedrock/index.ts +1 -1
- package/src/libs/agent-runtime/groq/index.test.ts +42 -1
- package/src/libs/agent-runtime/groq/index.ts +4 -1
- package/src/libs/agent-runtime/minimax/index.test.ts +1 -1
- package/src/libs/agent-runtime/minimax/index.ts +4 -1
- package/src/libs/agent-runtime/mistral/index.test.ts +2 -2
- package/src/libs/agent-runtime/mistral/index.ts +4 -1
- package/src/libs/agent-runtime/moonshot/index.ts +16 -1
- package/src/libs/agent-runtime/ollama/index.test.ts +27 -0
- package/src/libs/agent-runtime/ollama/index.ts +4 -1
- package/src/libs/agent-runtime/perplexity/index.test.ts +42 -0
- package/src/libs/agent-runtime/perplexity/index.ts +7 -2
- package/src/libs/agent-runtime/qwen/index.test.ts +47 -0
- package/src/libs/agent-runtime/qwen/index.ts +5 -1
- package/src/libs/agent-runtime/taichu/index.test.ts +48 -0
- package/src/libs/agent-runtime/taichu/index.ts +20 -1
- package/src/libs/agent-runtime/types/chat.ts +1 -1
- package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +1 -1
- package/src/types/llm.ts +1 -1
- package/src/types/openai/chat.ts +1 -1
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,48 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.15.21](https://github.com/lobehub/lobe-chat/compare/v1.15.20...v1.15.21)
|
6
|
+
|
7
|
+
<sup>Released on **2024-09-08**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Temperature range from 0 to 2.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Temperature range from 0 to 2, closes [#3355](https://github.com/lobehub/lobe-chat/issues/3355) ([4a9114e](https://github.com/lobehub/lobe-chat/commit/4a9114e))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.15.20](https://github.com/lobehub/lobe-chat/compare/v1.15.19...v1.15.20)
|
31
|
+
|
32
|
+
<sup>Released on **2024-09-08**</sup>
|
33
|
+
|
34
|
+
<br/>
|
35
|
+
|
36
|
+
<details>
|
37
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
38
|
+
|
39
|
+
</details>
|
40
|
+
|
41
|
+
<div align="right">
|
42
|
+
|
43
|
+
[](#readme-top)
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
5
47
|
### [Version 1.15.19](https://github.com/lobehub/lobe-chat/compare/v1.15.18...v1.15.19)
|
6
48
|
|
7
49
|
<sup>Released on **2024-09-08**</sup>
|
@@ -8,7 +8,7 @@ KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
|
|
8
8
|
# Required: Postgres database connection string
|
9
9
|
# Format: postgresql://username:password@host:port/dbname
|
10
10
|
# If using Docker, you can use the container name as the host
|
11
|
-
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/
|
11
|
+
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
|
12
12
|
|
13
13
|
# NEXT_AUTH related environment variables
|
14
14
|
# Supports auth0, Azure AD, GitHub, Authentik, Zitadel, Logto, etc.
|
@@ -7,7 +7,7 @@ APP_URL=https://lobe.example.com/
|
|
7
7
|
KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
|
8
8
|
# 必填,Postgres 数据库连接字符串,用于连接到数据库
|
9
9
|
# 格式:postgresql://username:password@host:port/dbname,如果你的 pg 实例为 Docker 容器且位于同一 docker-compose 文件中,亦可使用容器名作为 host
|
10
|
-
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/
|
10
|
+
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
|
11
11
|
|
12
12
|
# NEXT_AUTH 相关,也即鉴权服务必需的环境变量
|
13
13
|
# 可以使用 auth0、Azure AD、GitHub、Authentik、Zitadel、Logto 等,如有其他接入诉求欢迎提 PR
|
@@ -503,7 +503,7 @@ KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
|
|
503
503
|
# Required: Postgres database connection string
|
504
504
|
# Format: postgresql://username:password@host:port/dbname
|
505
505
|
# If using Docker, you can use the container name as the host
|
506
|
-
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/
|
506
|
+
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
|
507
507
|
|
508
508
|
# NEXT_AUTH related environment variables
|
509
509
|
# Supports auth0, Azure AD, GitHub, Authentik, Zitadel, Logto, etc.
|
@@ -499,7 +499,7 @@ APP_URL=https://lobe.example.com/
|
|
499
499
|
KEY_VAULTS_SECRET=Kix2wcUONd4CX51E/ZPAd36BqM4wzJgKjPtz2sGztqQ=
|
500
500
|
# 必填,Postgres 数据库连接字符串,用于连接到数据库
|
501
501
|
# 格式:postgresql://username:password@host:port/dbname,如果你的 pg 实例为 Docker 容器且位于同一 docker-compose 文件中,亦可使用容器名作为 host
|
502
|
-
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/
|
502
|
+
DATABASE_URL=postgresql://postgres:uWNZugjBqixf8dxC@postgresql:5432/lobe
|
503
503
|
|
504
504
|
# NEXT_AUTH 相关,也即鉴权服务必需的环境变量
|
505
505
|
# 可以使用 auth0、Azure AD、GitHub、Authentik、Zitadel、Logto 等,如有其他接入诉求欢迎提 PR
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.15.
|
3
|
+
"version": "1.15.21",
|
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",
|
@@ -32,7 +32,7 @@ export const AgentSchema = z.object({
|
|
32
32
|
frequency_penalty: z.number().default(0).optional(),
|
33
33
|
max_tokens: z.number().optional(),
|
34
34
|
presence_penalty: z.number().default(0).optional(),
|
35
|
-
temperature: z.number().default(
|
35
|
+
temperature: z.number().default(1).optional(),
|
36
36
|
top_p: z.number().default(1).optional(),
|
37
37
|
}),
|
38
38
|
plugins: z.array(z.string()).optional(),
|
@@ -36,7 +36,7 @@ const AgentModal = memo(() => {
|
|
36
36
|
tag: 'model',
|
37
37
|
},
|
38
38
|
{
|
39
|
-
children: <SliderWithInput max={
|
39
|
+
children: <SliderWithInput max={2} min={0} step={0.1} />,
|
40
40
|
desc: t('settingModel.temperature.desc'),
|
41
41
|
label: t('settingModel.temperature.title'),
|
42
42
|
name: ['params', 'temperature'],
|
@@ -107,7 +107,7 @@ const VirtualizedList = memo<VirtualizedListProps>(({ mobile }) => {
|
|
107
107
|
computeItemKey={(_, item) => item}
|
108
108
|
data={data}
|
109
109
|
followOutput={getFollowOutput}
|
110
|
-
|
110
|
+
increaseViewportBy={overscan}
|
111
111
|
initialTopMostItemIndex={data?.length - 1}
|
112
112
|
isScrolling={setIsScrolling}
|
113
113
|
itemContent={itemContent}
|
@@ -155,7 +155,7 @@ describe('LobeAnthropicAI', () => {
|
|
155
155
|
messages: [{ content: 'Hello', role: 'user' }],
|
156
156
|
model: 'claude-3-haiku-20240307',
|
157
157
|
stream: true,
|
158
|
-
temperature: 0.
|
158
|
+
temperature: 0.25,
|
159
159
|
top_p: 1,
|
160
160
|
},
|
161
161
|
{},
|
@@ -192,7 +192,7 @@ describe('LobeAnthropicAI', () => {
|
|
192
192
|
messages: [{ content: 'Hello', role: 'user' }],
|
193
193
|
model: 'claude-3-haiku-20240307',
|
194
194
|
stream: true,
|
195
|
-
temperature: 0.
|
195
|
+
temperature: 0.25,
|
196
196
|
top_p: 1,
|
197
197
|
},
|
198
198
|
{},
|
@@ -96,7 +96,10 @@ export class LobeAnthropicAI implements LobeRuntimeAI {
|
|
96
96
|
messages: buildAnthropicMessages(user_messages),
|
97
97
|
model,
|
98
98
|
system: system_message?.content as string,
|
99
|
-
temperature
|
99
|
+
temperature:
|
100
|
+
payload.temperature !== undefined
|
101
|
+
? temperature / 2
|
102
|
+
: undefined,
|
100
103
|
tools: buildAnthropicTools(tools),
|
101
104
|
top_p,
|
102
105
|
} satisfies Anthropic.MessageCreateParams;
|
@@ -192,7 +192,7 @@ describe('LobeBedrockAI', () => {
|
|
192
192
|
anthropic_version: 'bedrock-2023-05-31',
|
193
193
|
max_tokens: 2048,
|
194
194
|
messages: [{ content: 'Hello', role: 'user' }],
|
195
|
-
temperature: 0.
|
195
|
+
temperature: 0.25,
|
196
196
|
top_p: 1,
|
197
197
|
}),
|
198
198
|
contentType: 'application/json',
|
@@ -230,7 +230,7 @@ describe('LobeBedrockAI', () => {
|
|
230
230
|
anthropic_version: 'bedrock-2023-05-31',
|
231
231
|
max_tokens: 2048,
|
232
232
|
messages: [{ content: 'Hello', role: 'user' }],
|
233
|
-
temperature: 0.
|
233
|
+
temperature: 0.25,
|
234
234
|
top_p: 1,
|
235
235
|
}),
|
236
236
|
contentType: 'application/json',
|
@@ -64,7 +64,7 @@ export class LobeBedrockAI implements LobeRuntimeAI {
|
|
64
64
|
max_tokens: max_tokens || 4096,
|
65
65
|
messages: buildAnthropicMessages(user_messages),
|
66
66
|
system: system_message?.content as string,
|
67
|
-
temperature: temperature,
|
67
|
+
temperature: temperature / 2,
|
68
68
|
tools: buildAnthropicTools(tools),
|
69
69
|
top_p: top_p,
|
70
70
|
}),
|
@@ -2,7 +2,7 @@
|
|
2
2
|
import OpenAI from 'openai';
|
3
3
|
import { Mock, afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
4
4
|
|
5
|
-
import {
|
5
|
+
import { LobeOpenAICompatibleRuntime } from '@/libs/agent-runtime';
|
6
6
|
|
7
7
|
import * as debugStreamModule from '../utils/debugStream';
|
8
8
|
import { LobeGroq } from './index';
|
@@ -318,3 +318,44 @@ describe('LobeGroqAI', () => {
|
|
318
318
|
});
|
319
319
|
});
|
320
320
|
});
|
321
|
+
|
322
|
+
describe('LobeGroqAI Temperature Tests', () => {
|
323
|
+
it('should set temperature to 0.7', async () => {
|
324
|
+
await instance.chat({
|
325
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
326
|
+
model: 'mistralai/mistral-7b-instruct:free',
|
327
|
+
temperature: 0.7,
|
328
|
+
});
|
329
|
+
|
330
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
331
|
+
expect.objectContaining({ temperature: 0.7 }),
|
332
|
+
expect.anything(),
|
333
|
+
);
|
334
|
+
});
|
335
|
+
|
336
|
+
it('should set temperature to 0', async () => {
|
337
|
+
await instance.chat({
|
338
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
339
|
+
model: 'mistralai/mistral-7b-instruct:free',
|
340
|
+
temperature: 0,
|
341
|
+
});
|
342
|
+
|
343
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
344
|
+
expect.objectContaining({ temperature: undefined }),
|
345
|
+
expect.anything(),
|
346
|
+
);
|
347
|
+
});
|
348
|
+
|
349
|
+
it('should set temperature to negative', async () => {
|
350
|
+
await instance.chat({
|
351
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
352
|
+
model: 'mistralai/mistral-7b-instruct:free',
|
353
|
+
temperature: -1.0,
|
354
|
+
});
|
355
|
+
|
356
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
357
|
+
expect.objectContaining({ temperature: undefined }),
|
358
|
+
expect.anything(),
|
359
|
+
);
|
360
|
+
});
|
361
|
+
});
|
@@ -11,10 +11,13 @@ export const LobeGroq = LobeOpenAICompatibleFactory({
|
|
11
11
|
return { error, errorType: AgentRuntimeErrorType.LocationNotSupportError };
|
12
12
|
},
|
13
13
|
handlePayload: (payload) => {
|
14
|
+
const { temperature, ...restPayload } = payload;
|
14
15
|
return {
|
15
|
-
...
|
16
|
+
...restPayload,
|
16
17
|
// disable stream for tools due to groq dont support
|
17
18
|
stream: !payload.tools,
|
19
|
+
|
20
|
+
temperature: temperature <= 0 ? undefined : temperature,
|
18
21
|
} as any;
|
19
22
|
},
|
20
23
|
},
|
@@ -141,7 +141,10 @@ export class LobeMinimaxAI implements LobeRuntimeAI {
|
|
141
141
|
...params,
|
142
142
|
max_tokens: this.getMaxTokens(payload.model),
|
143
143
|
stream: true,
|
144
|
-
temperature:
|
144
|
+
temperature:
|
145
|
+
temperature === undefined || temperature <= 0
|
146
|
+
? undefined
|
147
|
+
: temperature / 2,
|
145
148
|
|
146
149
|
tools: params.tools?.map((tool) => ({
|
147
150
|
function: {
|
@@ -81,7 +81,7 @@ describe('LobeMistralAI', () => {
|
|
81
81
|
messages: [{ content: 'Hello', role: 'user' }],
|
82
82
|
model: 'open-mistral-7b',
|
83
83
|
stream: true,
|
84
|
-
temperature: 0.
|
84
|
+
temperature: 0.35,
|
85
85
|
top_p: 1,
|
86
86
|
},
|
87
87
|
{ headers: { Accept: '*/*' } },
|
@@ -114,7 +114,7 @@ describe('LobeMistralAI', () => {
|
|
114
114
|
messages: [{ content: 'Hello', role: 'user' }],
|
115
115
|
model: 'open-mistral-7b',
|
116
116
|
stream: true,
|
117
|
-
temperature: 0.
|
117
|
+
temperature: 0.35,
|
118
118
|
top_p: 1,
|
119
119
|
},
|
120
120
|
{ headers: { Accept: '*/*' } },
|
@@ -9,7 +9,10 @@ export const LobeMistralAI = LobeOpenAICompatibleFactory({
|
|
9
9
|
messages: payload.messages as any,
|
10
10
|
model: payload.model,
|
11
11
|
stream: true,
|
12
|
-
temperature:
|
12
|
+
temperature:
|
13
|
+
payload.temperature !== undefined
|
14
|
+
? payload.temperature / 2
|
15
|
+
: undefined,
|
13
16
|
...payload.tools && { tools: payload.tools },
|
14
17
|
top_p: payload.top_p,
|
15
18
|
}),
|
@@ -1,8 +1,23 @@
|
|
1
|
-
import
|
1
|
+
import OpenAI from 'openai';
|
2
|
+
|
3
|
+
import { ChatStreamPayload, ModelProvider } from '../types';
|
2
4
|
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
5
|
|
4
6
|
export const LobeMoonshotAI = LobeOpenAICompatibleFactory({
|
5
7
|
baseURL: 'https://api.moonshot.cn/v1',
|
8
|
+
chatCompletion: {
|
9
|
+
handlePayload: (payload: ChatStreamPayload) => {
|
10
|
+
const { temperature, ...rest } = payload;
|
11
|
+
|
12
|
+
return {
|
13
|
+
...rest,
|
14
|
+
temperature:
|
15
|
+
temperature !== undefined
|
16
|
+
? temperature / 2
|
17
|
+
: undefined,
|
18
|
+
} as OpenAI.ChatCompletionCreateParamsStreaming;
|
19
|
+
},
|
20
|
+
},
|
6
21
|
debug: {
|
7
22
|
chatCompletion: () => process.env.DEBUG_MOONSHOT_CHAT_COMPLETION === '1',
|
8
23
|
},
|
@@ -103,6 +103,33 @@ describe('LobeOllamaAI', () => {
|
|
103
103
|
|
104
104
|
expect(abortMock).toHaveBeenCalled();
|
105
105
|
});
|
106
|
+
|
107
|
+
it('temperature should be divided by two', async () => {
|
108
|
+
const chatMock = vi.fn().mockResolvedValue({});
|
109
|
+
vi.mocked(Ollama.prototype.chat).mockImplementation(chatMock);
|
110
|
+
|
111
|
+
const payload = {
|
112
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
113
|
+
model: 'model-id',
|
114
|
+
temperature: 0.7,
|
115
|
+
};
|
116
|
+
const options = { signal: new AbortController().signal };
|
117
|
+
|
118
|
+
const response = await ollamaAI.chat(payload as any, options);
|
119
|
+
|
120
|
+
expect(chatMock).toHaveBeenCalledWith({
|
121
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
122
|
+
model: 'model-id',
|
123
|
+
options: {
|
124
|
+
frequency_penalty: undefined,
|
125
|
+
presence_penalty: undefined,
|
126
|
+
temperature: 0.35,
|
127
|
+
top_p: undefined,
|
128
|
+
},
|
129
|
+
stream: true,
|
130
|
+
});
|
131
|
+
expect(response).toBeInstanceOf(Response);
|
132
|
+
});
|
106
133
|
});
|
107
134
|
|
108
135
|
describe('models', () => {
|
@@ -45,7 +45,10 @@ export class LobeOllamaAI implements LobeRuntimeAI {
|
|
45
45
|
options: {
|
46
46
|
frequency_penalty: payload.frequency_penalty,
|
47
47
|
presence_penalty: payload.presence_penalty,
|
48
|
-
temperature:
|
48
|
+
temperature:
|
49
|
+
payload.temperature !== undefined
|
50
|
+
? payload.temperature / 2
|
51
|
+
: undefined,
|
49
52
|
top_p: payload.top_p,
|
50
53
|
},
|
51
54
|
stream: true,
|
@@ -245,5 +245,47 @@ describe('LobePerplexityAI', () => {
|
|
245
245
|
process.env.DEBUG_PERPLEXITY_CHAT_COMPLETION = originalDebugValue;
|
246
246
|
});
|
247
247
|
});
|
248
|
+
|
249
|
+
it('should call chat method with temperature', async () => {
|
250
|
+
vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
|
251
|
+
new ReadableStream() as any,
|
252
|
+
);
|
253
|
+
|
254
|
+
await instance.chat({
|
255
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
256
|
+
model: 'text-davinci-003',
|
257
|
+
temperature: 1.5,
|
258
|
+
});
|
259
|
+
|
260
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
261
|
+
expect.objectContaining({
|
262
|
+
messages: expect.any(Array),
|
263
|
+
model: 'text-davinci-003',
|
264
|
+
temperature: 1.5,
|
265
|
+
}),
|
266
|
+
expect.any(Object),
|
267
|
+
);
|
268
|
+
});
|
269
|
+
|
270
|
+
it('should be undefined when temperature >= 2', async () => {
|
271
|
+
vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
|
272
|
+
new ReadableStream() as any,
|
273
|
+
);
|
274
|
+
|
275
|
+
await instance.chat({
|
276
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
277
|
+
model: 'text-davinci-003',
|
278
|
+
temperature: 2,
|
279
|
+
});
|
280
|
+
|
281
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
282
|
+
expect.objectContaining({
|
283
|
+
messages: expect.any(Array),
|
284
|
+
model: 'text-davinci-003',
|
285
|
+
temperature: undefined,
|
286
|
+
}),
|
287
|
+
expect.any(Object),
|
288
|
+
);
|
289
|
+
});
|
248
290
|
});
|
249
291
|
});
|
@@ -8,7 +8,7 @@ export const LobePerplexityAI = LobeOpenAICompatibleFactory({
|
|
8
8
|
chatCompletion: {
|
9
9
|
handlePayload: (payload: ChatStreamPayload) => {
|
10
10
|
// Set a default frequency penalty value greater than 0
|
11
|
-
const { presence_penalty, frequency_penalty, stream = true, ...res } = payload;
|
11
|
+
const { presence_penalty, frequency_penalty, stream = true, temperature, ...res } = payload;
|
12
12
|
|
13
13
|
let param;
|
14
14
|
|
@@ -21,7 +21,12 @@ export const LobePerplexityAI = LobeOpenAICompatibleFactory({
|
|
21
21
|
param = { frequency_penalty: frequency_penalty || defaultFrequencyPenalty };
|
22
22
|
}
|
23
23
|
|
24
|
-
return {
|
24
|
+
return {
|
25
|
+
...res,
|
26
|
+
...param,
|
27
|
+
stream,
|
28
|
+
temperature: temperature >= 2 ? undefined : temperature,
|
29
|
+
} as OpenAI.ChatCompletionCreateParamsStreaming;
|
25
30
|
},
|
26
31
|
},
|
27
32
|
debug: {
|
@@ -152,6 +152,53 @@ describe('LobeQwenAI', () => {
|
|
152
152
|
|
153
153
|
expect((await reader.read()).done).toBe(true);
|
154
154
|
});
|
155
|
+
|
156
|
+
it('should set temperature to undefined if temperature is 0 or >= 2', async () => {
|
157
|
+
const temperatures = [0, 2, 3];
|
158
|
+
const expectedTemperature = undefined;
|
159
|
+
|
160
|
+
for (const temp of temperatures) {
|
161
|
+
vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
|
162
|
+
new ReadableStream() as any,
|
163
|
+
);
|
164
|
+
|
165
|
+
await instance.chat({
|
166
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
167
|
+
model: 'qwen-turbo',
|
168
|
+
temperature: temp,
|
169
|
+
});
|
170
|
+
|
171
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
172
|
+
expect.objectContaining({
|
173
|
+
messages: expect.any(Array),
|
174
|
+
model: 'qwen-turbo',
|
175
|
+
temperature: expectedTemperature,
|
176
|
+
}),
|
177
|
+
expect.any(Object),
|
178
|
+
);
|
179
|
+
}
|
180
|
+
});
|
181
|
+
|
182
|
+
it('should set temperature to original temperature', async () => {
|
183
|
+
vi.spyOn(instance['client'].chat.completions, 'create').mockResolvedValue(
|
184
|
+
new ReadableStream() as any,
|
185
|
+
);
|
186
|
+
|
187
|
+
await instance.chat({
|
188
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
189
|
+
model: 'qwen-turbo',
|
190
|
+
temperature: 1.5,
|
191
|
+
});
|
192
|
+
|
193
|
+
expect(instance['client'].chat.completions.create).toHaveBeenCalledWith(
|
194
|
+
expect.objectContaining({
|
195
|
+
messages: expect.any(Array),
|
196
|
+
model: 'qwen-turbo',
|
197
|
+
temperature: 1.5,
|
198
|
+
}),
|
199
|
+
expect.any(Object),
|
200
|
+
);
|
201
|
+
});
|
155
202
|
});
|
156
203
|
|
157
204
|
describe('Error', () => {
|
@@ -100,7 +100,7 @@ export class LobeQwenAI implements LobeRuntimeAI {
|
|
100
100
|
}
|
101
101
|
|
102
102
|
private buildCompletionParamsByModel(payload: ChatStreamPayload) {
|
103
|
-
const { model, top_p, stream, messages, tools } = payload;
|
103
|
+
const { model, temperature, top_p, stream, messages, tools } = payload;
|
104
104
|
const isVisionModel = model.startsWith('qwen-vl');
|
105
105
|
|
106
106
|
const params = {
|
@@ -108,6 +108,10 @@ export class LobeQwenAI implements LobeRuntimeAI {
|
|
108
108
|
messages,
|
109
109
|
result_format: 'message',
|
110
110
|
stream: !!tools?.length ? false : (stream ?? true),
|
111
|
+
temperature:
|
112
|
+
temperature === 0 || temperature >= 2
|
113
|
+
? undefined
|
114
|
+
: temperature,
|
111
115
|
top_p: top_p && top_p >= 1 ? 0.999 : top_p,
|
112
116
|
};
|
113
117
|
|
@@ -251,5 +251,53 @@ describe('LobeTaichuAI', () => {
|
|
251
251
|
process.env.DEBUG_TAICHU_CHAT_COMPLETION = originalDebugValue;
|
252
252
|
});
|
253
253
|
});
|
254
|
+
|
255
|
+
it('should correctly adjust temperature and top_p parameters', async () => {
|
256
|
+
const instance = new LobeTaichuAI({ apiKey: 'test_api_key' });
|
257
|
+
|
258
|
+
// Mock the chat.completions.create method
|
259
|
+
const errorInfo = {
|
260
|
+
stack: 'abc',
|
261
|
+
cause: {
|
262
|
+
message: 'api is undefined',
|
263
|
+
},
|
264
|
+
};
|
265
|
+
const apiError = new OpenAI.APIError(400, errorInfo, 'module error', {});
|
266
|
+
|
267
|
+
const mockCreate = vi
|
268
|
+
.spyOn(instance['client'].chat.completions, 'create')
|
269
|
+
.mockRejectedValue(apiError);
|
270
|
+
|
271
|
+
// Test cases for temperature and top_p
|
272
|
+
const testCases = [
|
273
|
+
{ temperature: 0.5, top_p: 0.5, expectedTemperature: 0.25, expectedTopP: 0.25 },
|
274
|
+
{ temperature: 1.0, top_p: 1.0, expectedTemperature: 0.5, expectedTopP: 0.5 },
|
275
|
+
{ temperature: 2.0, top_p: 2.0, expectedTemperature: 1.0, expectedTopP: 1.0 },
|
276
|
+
{ temperature: 1.0, top_p: undefined, expectedTemperature: 0.5, expectedTopP: undefined },
|
277
|
+
{ temperature: 0, top_p: 0.1, expectedTemperature: 0.01, expectedTopP: 0.1 },
|
278
|
+
{ temperature: 0.01, top_p: 0.0, expectedTemperature: 0.01, expectedTopP: 0.1 },
|
279
|
+
{ temperature: 0.02, top_p: 20.0, expectedTemperature: 0.01, expectedTopP: 9.9 },
|
280
|
+
];
|
281
|
+
|
282
|
+
for (const { temperature, top_p, expectedTemperature, expectedTopP } of testCases) {
|
283
|
+
try {
|
284
|
+
await instance.chat({
|
285
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
286
|
+
model: 'Taichu4',
|
287
|
+
temperature,
|
288
|
+
top_p,
|
289
|
+
stream: true,
|
290
|
+
});
|
291
|
+
|
292
|
+
expect(mockCreate).toHaveBeenCalledWith(
|
293
|
+
expect.objectContaining({
|
294
|
+
temperature: expectedTemperature,
|
295
|
+
top_p: expectedTopP,
|
296
|
+
}),
|
297
|
+
expect.objectContaining({}),
|
298
|
+
);
|
299
|
+
} catch (e) {}
|
300
|
+
}
|
301
|
+
});
|
254
302
|
});
|
255
303
|
});
|
@@ -1,8 +1,27 @@
|
|
1
|
-
import
|
1
|
+
import OpenAI from 'openai';
|
2
|
+
|
3
|
+
import { ChatStreamPayload, ModelProvider } from '../types';
|
2
4
|
import { LobeOpenAICompatibleFactory } from '../utils/openaiCompatibleFactory';
|
3
5
|
|
4
6
|
export const LobeTaichuAI = LobeOpenAICompatibleFactory({
|
5
7
|
baseURL: 'https://ai-maas.wair.ac.cn/maas/v1',
|
8
|
+
chatCompletion: {
|
9
|
+
handlePayload: (payload: ChatStreamPayload) => {
|
10
|
+
const { temperature, top_p, ...rest } = payload;
|
11
|
+
|
12
|
+
return {
|
13
|
+
...rest,
|
14
|
+
temperature:
|
15
|
+
temperature !== undefined
|
16
|
+
? Math.max(temperature / 2, 0.01)
|
17
|
+
: undefined,
|
18
|
+
top_p:
|
19
|
+
top_p !== undefined
|
20
|
+
? Math.min(9.9, Math.max(top_p / 2, 0.1))
|
21
|
+
: undefined
|
22
|
+
} as OpenAI.ChatCompletionCreateParamsStreaming;
|
23
|
+
},
|
24
|
+
},
|
6
25
|
debug: {
|
7
26
|
chatCompletion: () => process.env.DEBUG_TAICHU_CHAT_COMPLETION === '1',
|
8
27
|
},
|
package/src/types/llm.ts
CHANGED