@lobehub/chat 0.117.2 → 0.117.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/CHANGELOG.md +27 -0
- package/package.json +1 -1
- package/src/chains/__tests__/summaryTitle.test.ts +0 -1
- package/src/const/llm.ts +16 -1
- package/src/const/message.ts +10 -1
- package/src/const/settings.ts +0 -2
- package/src/features/AgentSetting/AgentPrompt/index.tsx +1 -1
- package/src/features/ChatInput/ActionBar/Token/TokenTag.tsx +1 -1
- package/src/features/Conversation/ChatList/Messages/Assistant.tsx +1 -1
- package/src/features/PluginDevModal/UrlManifestForm.tsx +20 -17
- package/src/services/__tests__/chat.test.ts +1 -2
- package/src/services/chat.ts +1 -3
- package/src/store/chat/slices/message/action.ts +6 -7
- package/src/store/session/slices/agent/selectors.ts +2 -2
- package/src/const/modelTokens.ts +0 -12
- package/src/utils/message.ts +0 -28
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,33 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.117.3](https://github.com/lobehub/lobe-chat/compare/v0.117.2...v0.117.3)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2023-12-28**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Fix tool calls at end, fix vision model max tokens, improve vision model checker.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Fix tool calls at end ([b0b615a](https://github.com/lobehub/lobe-chat/commit/b0b615a))
|
|
21
|
+
- **misc**: Fix vision model max tokens ([8b704a0](https://github.com/lobehub/lobe-chat/commit/8b704a0))
|
|
22
|
+
- **misc**: Improve vision model checker ([da7d177](https://github.com/lobehub/lobe-chat/commit/da7d177))
|
|
23
|
+
|
|
24
|
+
</details>
|
|
25
|
+
|
|
26
|
+
<div align="right">
|
|
27
|
+
|
|
28
|
+
[](#readme-top)
|
|
29
|
+
|
|
30
|
+
</div>
|
|
31
|
+
|
|
5
32
|
### [Version 0.117.2](https://github.com/lobehub/lobe-chat/compare/v0.117.1...v0.117.2)
|
|
6
33
|
|
|
7
34
|
<sup>Released on **2023-12-28**</sup>
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.117.
|
|
3
|
+
"version": "0.117.3",
|
|
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",
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Mock, describe, expect, it, vi } from 'vitest';
|
|
2
2
|
|
|
3
|
-
import { ModelTokens } from '@/const/modelTokens';
|
|
4
3
|
import { chatHelpers } from '@/store/chat/helpers';
|
|
5
4
|
import { globalHelpers } from '@/store/global/helpers';
|
|
6
5
|
import { LanguageModel } from '@/types/llm';
|
package/src/const/llm.ts
CHANGED
|
@@ -14,4 +14,19 @@ export const LanguageModelWhiteList = [
|
|
|
14
14
|
export const DEFAULT_OPENAI_MODEL_LIST: string[] = Object.values(LanguageModel);
|
|
15
15
|
|
|
16
16
|
// vision model white list, these models will change the content from string to array
|
|
17
|
-
|
|
17
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/790
|
|
18
|
+
export const isVisionModel = (model?: string) => !!model && model.includes('vision');
|
|
19
|
+
|
|
20
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/837
|
|
21
|
+
export const GPT4_VISION_MODEL_DEFAULT_MAX_TOKENS = 2048;
|
|
22
|
+
|
|
23
|
+
// refs to: https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo
|
|
24
|
+
export const ModelTokens: Record<LanguageModel, number> = {
|
|
25
|
+
[LanguageModel.GPT3_5]: 4096,
|
|
26
|
+
[LanguageModel.GPT3_5_1106]: 16_385,
|
|
27
|
+
[LanguageModel.GPT3_5_16K]: 16_385,
|
|
28
|
+
[LanguageModel.GPT4]: 8196,
|
|
29
|
+
[LanguageModel.GPT4_PREVIEW]: 128_000,
|
|
30
|
+
[LanguageModel.GPT4_VISION_PREVIEW]: 128_000,
|
|
31
|
+
[LanguageModel.GPT4_32K]: 32_768,
|
|
32
|
+
};
|
package/src/const/message.ts
CHANGED
|
@@ -3,4 +3,13 @@ export const LOADING_FLAT = '...';
|
|
|
3
3
|
// start with this,it should be a function message
|
|
4
4
|
export const FUNCTION_MESSAGE_FLAG = '{"tool_calls"';
|
|
5
5
|
|
|
6
|
-
export const
|
|
6
|
+
export const isFunctionMessageAtStart = (content: string) => {
|
|
7
|
+
return content.startsWith(FUNCTION_MESSAGE_FLAG);
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
export const testFunctionMessageAtEnd = (content: string) => {
|
|
11
|
+
const regExp = /{"tool_calls":.*?}}/;
|
|
12
|
+
const match = content.match(regExp);
|
|
13
|
+
|
|
14
|
+
return { content: match ? match[0] : '', valid: match };
|
|
15
|
+
};
|
package/src/const/settings.ts
CHANGED
|
@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
|
8
8
|
|
|
9
9
|
import { FORM_STYLE } from '@/const/layoutTokens';
|
|
10
|
-
import { ModelTokens } from '@/const/
|
|
10
|
+
import { ModelTokens } from '@/const/llm';
|
|
11
11
|
import { useTokenCount } from '@/hooks/useTokenCount';
|
|
12
12
|
import { LanguageModel } from '@/types/llm';
|
|
13
13
|
|
|
@@ -2,7 +2,7 @@ import { TokenTag, Tooltip } from '@lobehub/ui';
|
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
|
|
5
|
-
import { ModelTokens } from '@/const/
|
|
5
|
+
import { ModelTokens } from '@/const/llm';
|
|
6
6
|
import { useTokenCount } from '@/hooks/useTokenCount';
|
|
7
7
|
import { useChatStore } from '@/store/chat';
|
|
8
8
|
import { chatSelectors } from '@/store/chat/selectors';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { ReactNode, memo } from 'react';
|
|
2
2
|
|
|
3
|
+
import { isFunctionMessageAtStart } from '@/const/message';
|
|
3
4
|
import { useChatStore } from '@/store/chat';
|
|
4
5
|
import { chatSelectors } from '@/store/chat/selectors';
|
|
5
6
|
import { ChatMessage } from '@/types/message';
|
|
6
|
-
import { isFunctionMessageAtStart } from '@/utils/message';
|
|
7
7
|
|
|
8
8
|
import Inspector from '../Plugins/Inspector';
|
|
9
9
|
import { DefaultMessage } from './Default';
|
|
@@ -12,24 +12,27 @@ import { useToolStore } from '@/store/tool';
|
|
|
12
12
|
import { pluginSelectors } from '@/store/tool/selectors';
|
|
13
13
|
import { PluginInstallError } from '@/types/tool/plugin';
|
|
14
14
|
|
|
15
|
-
|
|
16
|
-
(
|
|
17
|
-
|
|
15
|
+
interface ProxyCheckerProps {
|
|
16
|
+
onChange?: (value: boolean) => void;
|
|
17
|
+
value?: boolean;
|
|
18
|
+
}
|
|
18
19
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
20
|
+
const ProxyChecker = memo<ProxyCheckerProps>(({ value, onChange }) => {
|
|
21
|
+
const { t } = useTranslation('plugin');
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<Flexbox
|
|
25
|
+
gap={8}
|
|
26
|
+
horizontal
|
|
27
|
+
onClick={() => {
|
|
28
|
+
onChange?.(!value);
|
|
29
|
+
}}
|
|
30
|
+
style={{ cursor: 'pointer' }}
|
|
31
|
+
>
|
|
32
|
+
<Checkbox checked={value} /> {t('dev.customParams.useProxy.label')}
|
|
33
|
+
</Flexbox>
|
|
34
|
+
);
|
|
35
|
+
});
|
|
33
36
|
|
|
34
37
|
const UrlManifestForm = memo<{ form: FormInstance; isEditMode: boolean }>(
|
|
35
38
|
({ form, isEditMode }) => {
|
|
@@ -2,7 +2,6 @@ import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
|
|
2
2
|
import { act } from '@testing-library/react';
|
|
3
3
|
import { describe, expect, it, vi } from 'vitest';
|
|
4
4
|
|
|
5
|
-
import { VISION_MODEL_WHITE_LIST } from '@/const/llm';
|
|
6
5
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
7
6
|
import { useFileStore } from '@/store/file';
|
|
8
7
|
import { useToolStore } from '@/store/tool';
|
|
@@ -74,7 +73,7 @@ describe('ChatService', () => {
|
|
|
74
73
|
it('should not use tools for models in the vision model whitelist', async () => {
|
|
75
74
|
const getChatCompletionSpy = vi.spyOn(chatService, 'getChatCompletion');
|
|
76
75
|
const messages = [{ content: 'Hello', role: 'user' }] as ChatMessage[];
|
|
77
|
-
const modelInWhitelist =
|
|
76
|
+
const modelInWhitelist = 'gpt-4-vision-preview';
|
|
78
77
|
|
|
79
78
|
await chatService.createAssistantMessage({
|
|
80
79
|
messages,
|
package/src/services/chat.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { PluginRequestPayload, createHeadersWithPluginSettings } from '@lobehub/
|
|
|
2
2
|
import { produce } from 'immer';
|
|
3
3
|
import { merge } from 'lodash-es';
|
|
4
4
|
|
|
5
|
-
import {
|
|
5
|
+
import { isVisionModel } from '@/const/llm';
|
|
6
6
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
|
7
7
|
import { filesSelectors, useFileStore } from '@/store/file';
|
|
8
8
|
import { useToolStore } from '@/store/tool';
|
|
@@ -15,8 +15,6 @@ import { fetchAIFactory, getMessageError } from '@/utils/fetch';
|
|
|
15
15
|
import { createHeaderWithOpenAI } from './_header';
|
|
16
16
|
import { OPENAI_URLS, PLUGINS_URLS } from './_url';
|
|
17
17
|
|
|
18
|
-
const isVisionModel = (model?: string) => model && VISION_MODEL_WHITE_LIST.includes(model);
|
|
19
|
-
|
|
20
18
|
interface FetchOptions {
|
|
21
19
|
signal?: AbortSignal | undefined;
|
|
22
20
|
}
|
|
@@ -5,9 +5,8 @@ import { template } from 'lodash-es';
|
|
|
5
5
|
import useSWR, { SWRResponse, mutate } from 'swr';
|
|
6
6
|
import { StateCreator } from 'zustand/vanilla';
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { LOADING_FLAT } from '@/const/message';
|
|
10
|
-
import { VISION_MODEL_DEFAULT_MAX_TOKENS } from '@/const/settings';
|
|
8
|
+
import { GPT4_VISION_MODEL_DEFAULT_MAX_TOKENS } from '@/const/llm';
|
|
9
|
+
import { LOADING_FLAT, isFunctionMessageAtStart, testFunctionMessageAtEnd } from '@/const/message';
|
|
11
10
|
import { CreateMessageParams } from '@/database/models/message';
|
|
12
11
|
import { DB_Message } from '@/database/schemas/message';
|
|
13
12
|
import { chatService } from '@/services/chat';
|
|
@@ -19,7 +18,6 @@ import { useSessionStore } from '@/store/session';
|
|
|
19
18
|
import { agentSelectors } from '@/store/session/selectors';
|
|
20
19
|
import { ChatMessage } from '@/types/message';
|
|
21
20
|
import { fetchSSE } from '@/utils/fetch';
|
|
22
|
-
import { isFunctionMessageAtStart, testFunctionMessageAtEnd } from '@/utils/message';
|
|
23
21
|
import { setNamespace } from '@/utils/storeDebug';
|
|
24
22
|
|
|
25
23
|
import { chatSelectors } from '../../selectors';
|
|
@@ -339,11 +337,12 @@ export const chatMessage: StateCreator<
|
|
|
339
337
|
config.params.max_tokens = config.enableMaxTokens ? config.params.max_tokens : undefined;
|
|
340
338
|
|
|
341
339
|
// 5. handle config for the vision model
|
|
342
|
-
// Due to vision model's default max_tokens is very small
|
|
340
|
+
// Due to the gpt-4-vision-preview model's default max_tokens is very small
|
|
343
341
|
// we need to set the max_tokens a larger one.
|
|
344
|
-
if (
|
|
342
|
+
if (config.model === 'gpt-4-vision-preview') {
|
|
345
343
|
/* eslint-disable unicorn/no-lonely-if */
|
|
346
|
-
if (!config.params.max_tokens)
|
|
344
|
+
if (!config.params.max_tokens)
|
|
345
|
+
config.params.max_tokens = GPT4_VISION_MODEL_DEFAULT_MAX_TOKENS;
|
|
347
346
|
}
|
|
348
347
|
|
|
349
348
|
const fetcher = () =>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { VoiceList } from '@lobehub/tts';
|
|
2
2
|
import { t } from 'i18next';
|
|
3
3
|
|
|
4
|
-
import { DEFAULT_OPENAI_MODEL_LIST,
|
|
4
|
+
import { DEFAULT_OPENAI_MODEL_LIST, isVisionModel } from '@/const/llm';
|
|
5
5
|
import { DEFAULT_AVATAR, DEFAULT_BACKGROUND_COLOR, DEFAULT_INBOX_AVATAR } from '@/const/meta';
|
|
6
6
|
import { DEFAULT_AGENT_CONFIG, DEFAUTT_AGENT_TTS_CONFIG } from '@/const/settings';
|
|
7
7
|
import { useGlobalStore } from '@/store/global';
|
|
@@ -109,7 +109,7 @@ const hasSystemRole = (s: SessionStore) => {
|
|
|
109
109
|
};
|
|
110
110
|
const modelHasVisionAbility = (s: SessionStore): boolean => {
|
|
111
111
|
const model = currentAgentModel(s);
|
|
112
|
-
return
|
|
112
|
+
return isVisionModel(model);
|
|
113
113
|
};
|
|
114
114
|
|
|
115
115
|
export const agentSelectors = {
|
package/src/const/modelTokens.ts
DELETED
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { LanguageModel } from '@/types/llm';
|
|
2
|
-
|
|
3
|
-
// refs to: https://platform.openai.com/docs/models/gpt-4-and-gpt-4-turbo
|
|
4
|
-
export const ModelTokens: Record<LanguageModel, number> = {
|
|
5
|
-
[LanguageModel.GPT3_5]: 4096,
|
|
6
|
-
[LanguageModel.GPT3_5_1106]: 16_385,
|
|
7
|
-
[LanguageModel.GPT3_5_16K]: 16_385,
|
|
8
|
-
[LanguageModel.GPT4]: 8196,
|
|
9
|
-
[LanguageModel.GPT4_PREVIEW]: 128_000,
|
|
10
|
-
[LanguageModel.GPT4_VISION_PREVIEW]: 128_000,
|
|
11
|
-
[LanguageModel.GPT4_32K]: 32_768,
|
|
12
|
-
};
|
package/src/utils/message.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { FUNCTION_MESSAGE_FLAG } from '@/const/message';
|
|
2
|
-
|
|
3
|
-
export const isFunctionMessageAtStart = (content: string) => {
|
|
4
|
-
return content.startsWith(FUNCTION_MESSAGE_FLAG);
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
export const testFunctionMessageAtEnd = (content: string) => {
|
|
8
|
-
const regExp = /{"function_call":.*?}}/;
|
|
9
|
-
const match = content.match(regExp);
|
|
10
|
-
|
|
11
|
-
return { content: match ? match[0] : '', valid: match };
|
|
12
|
-
};
|
|
13
|
-
|
|
14
|
-
// export const createFunctionCallMessage = () => {
|
|
15
|
-
// return [
|
|
16
|
-
// {
|
|
17
|
-
// content: '',
|
|
18
|
-
// function_call: { arguments: '{\n "city": "杭州"\n}', name: 'realtimeWeather' },
|
|
19
|
-
// role: 'assistant',
|
|
20
|
-
// },
|
|
21
|
-
// {
|
|
22
|
-
// content:
|
|
23
|
-
// '{"status":"1","count":"1","info":"OK","infocode":"10000","forecasts":[{"city":"杭州市","adcode":"300","province":"浙江","reporttime":"2023-07-28 20:32:48","casts":[{"date":"2023-07-28","week":"5","dayweather"小雨","nightweather":"小雨-中雨","daytemp":"32","nighttemp":"26","daywind":"东","nightwind":"东","daypower":"6power":"6","daytemp_float":"32.0","nighttemp_float":"26.0"},{"date":"2023-07-29","week":"6","dayweather":"小雨雨","nightweather":"小雨","daytemp":"30","nighttemp":"25","daywind":"东南","nightwind":"东南","daypower":"4","wer":"4","daytemp_float":"30.0","nighttemp_float":"25.0"},{"date":"2023-07-30","week":"7","dayweather":"小雨",ightweather":"雷阵雨","daytemp":"31","nighttemp":"25","daywind":"东南","nightwind":"东南","daypower":"4","nigh:"4","daytemp_float":"31.0","nighttemp_float":"25.0"},{"date":"2023-07-31","week":"1","dayweather":"雷阵雨","ntweather":"雷阵雨","daytemp":"33","nighttemp":"25","daywind":"东","nightwind":"东","daypower":"4","nightpower""daytemp_float":"33.0","nighttemp_float":"25.0"}]}]}',
|
|
24
|
-
// name: 'realtimeWeather',
|
|
25
|
-
// role: 'function',
|
|
26
|
-
// },
|
|
27
|
-
// ];
|
|
28
|
-
// };
|