@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 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
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#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.2",
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
- export const VISION_MODEL_WHITE_LIST = ['gpt-4-vision-preview'];
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
+ };
@@ -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 FUNCTION_LOADING = 'FUNCTION_LOADING';
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
+ };
@@ -27,8 +27,6 @@ export const DEFAUTT_AGENT_TTS_CONFIG: LobeAgentTTSConfig = {
27
27
  },
28
28
  };
29
29
 
30
- export const VISION_MODEL_DEFAULT_MAX_TOKENS = 1000;
31
-
32
30
  export const COOKIE_CACHE_DAYS = 30;
33
31
 
34
32
  export const DEFAULT_AGENT_CONFIG: LobeAgentConfig = {
@@ -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/modelTokens';
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/modelTokens';
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
- const ProxyChecker = memo<{ onChange?: (value: boolean) => void; value?: boolean }>(
16
- ({ value, onChange }) => {
17
- const { t } = useTranslation('plugin');
15
+ interface ProxyCheckerProps {
16
+ onChange?: (value: boolean) => void;
17
+ value?: boolean;
18
+ }
18
19
 
19
- return (
20
- <Flexbox
21
- gap={8}
22
- horizontal
23
- onClick={() => {
24
- onChange?.(!value);
25
- }}
26
- style={{ cursor: 'pointer' }}
27
- >
28
- <Checkbox checked={value} /> {t('dev.customParams.useProxy.label')}
29
- </Flexbox>
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 = VISION_MODEL_WHITE_LIST[0];
76
+ const modelInWhitelist = 'gpt-4-vision-preview';
78
77
 
79
78
  await chatService.createAssistantMessage({
80
79
  messages,
@@ -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 { VISION_MODEL_WHITE_LIST } from '@/const/llm';
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 { VISION_MODEL_WHITE_LIST } from '@/const/llm';
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 (VISION_MODEL_WHITE_LIST.includes(config.model)) {
342
+ if (config.model === 'gpt-4-vision-preview') {
345
343
  /* eslint-disable unicorn/no-lonely-if */
346
- if (!config.params.max_tokens) config.params.max_tokens = VISION_MODEL_DEFAULT_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, VISION_MODEL_WHITE_LIST } from '@/const/llm';
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 VISION_MODEL_WHITE_LIST.includes(model);
112
+ return isVisionModel(model);
113
113
  };
114
114
 
115
115
  export const agentSelectors = {
@@ -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
- };
@@ -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
- // };