@lobehub/chat 0.117.1 → 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,58 @@
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
+
32
+ ### [Version 0.117.2](https://github.com/lobehub/lobe-chat/compare/v0.117.1...v0.117.2)
33
+
34
+ <sup>Released on **2023-12-28**</sup>
35
+
36
+ #### 🐛 Bug Fixes
37
+
38
+ - **misc**: Fix market locale missing.
39
+
40
+ <br/>
41
+
42
+ <details>
43
+ <summary><kbd>Improvements and Fixes</kbd></summary>
44
+
45
+ #### What's fixed
46
+
47
+ - **misc**: Fix market locale missing, closes [#851](https://github.com/lobehub/lobe-chat/issues/851) ([e23ec66](https://github.com/lobehub/lobe-chat/commit/e23ec66))
48
+
49
+ </details>
50
+
51
+ <div align="right">
52
+
53
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
54
+
55
+ </div>
56
+
5
57
  ### [Version 0.117.1](https://github.com/lobehub/lobe-chat/compare/v0.117.0...v0.117.1)
6
58
 
7
59
  <sup>Released on **2023-12-27**</sup>
package/README.md CHANGED
@@ -211,11 +211,11 @@ Our marketplace is not just a showcase platform but also a collaborative space.
211
211
  | Recent Submits | Description |
212
212
  | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
213
213
  | [Deployment Specialist Agent](https://chat-preview.lobehub.com/market?agent=deployment-agent)<br/><sup>By **[amitalokbera](https://github.com/amitalokbera)** on **2023-12-27**</sup> | An AI Deployment Specialist is an expert in managing the full deployment lifecycle of software applications, particularly web applications.<br/>`code` `deployment` `software` |
214
+ | [Overview of Art Thesis Experts](https://chat-preview.lobehub.com/market?agent=thesis-overview)<br/><sup>By **[caoyang2002](https://github.com/caoyang2002)** on **2023-12-27**</sup> | Specializing in brief thesis and art criticism<br/>`art` `thesis` `critique` |
214
215
  | [American English Transcreation Expert](https://chat-preview.lobehub.com/market?agent=to-local-english)<br/><sup>By **[doresu](https://github.com/doresu)** on **2023-12-27**</sup> | Rough old editor, seasoned writer, and translator, proficient in translating English directly and transforming it into authentic American English<br/>`translation` `editing` `writing` `translator` |
215
216
  | [Academic Proofreading Expert](https://chat-preview.lobehub.com/market?agent=academic-paragraph-refiner)<br/><sup>By **[Feliks151450](https://github.com/Feliks151450)** on **2023-12-26**</sup> | Highly skilled in advanced research proofreading and language editing, specializing in multiple research fields and proficient in academic English.<br/>`proofreading` `writing` `research` |
216
- | [Flutter Maestro](https://chat-preview.lobehub.com/market?agent=flutter-dev)<br/><sup>By **[kamaravichow](https://github.com/kamaravichow)** on **2023-12-25**</sup> | A developer expert in Flutter framework and Dart programming language.<br/>`flutter` `development` `dart` `programming` `widgets` |
217
217
 
218
- > 📊 Total agents: [<kbd>**81**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
218
+ > 📊 Total agents: [<kbd>**82**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
219
219
 
220
220
  <!-- AGENT LIST -->
221
221
 
package/README.zh-CN.md CHANGED
@@ -184,14 +184,14 @@ LobeChat 的插件生态系统是其核心功能的重要扩展,它极大地
184
184
 
185
185
  <!-- AGENT LIST -->
186
186
 
187
- | 最近新增 | 助手说明 |
188
- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
189
- | [部署专家代理](https://chat-preview.lobehub.com/market?agent=deployment-agent)<br/><sup>By **[amitalokbera](https://github.com/amitalokbera)** on **2023-12-27**</sup> | AI 部署专家是管理软件应用的完整部署生命周期的专家,特别是 Web 应用。<br/>`代码` `部署` `容器化` |
190
- | [美式英语转译专家](https://chat-preview.lobehub.com/market?agent=to-local-english)<br/><sup>By **[doresu](https://github.com/doresu)** on **2023-12-27**</sup> | 粗鲁老编辑、资深作家和翻译家,擅长直译英文并转化为地道的美式英语<br/>`翻译` `编辑` `写作` `翻译家` |
191
- | [学术润色专家](https://chat-preview.lobehub.com/market?agent=academic-paragraph-refiner)<br/><sup>By **[Feliks151450](https://github.com/Feliks151450)** on **2023-12-26**</sup> | 高级研究校对及语言编辑,专业于多个研究领域,精通学术英语。<br/>`校对` `写作` `研究` |
192
- | [Flutter 开发专家](https://chat-preview.lobehub.com/market?agent=flutter-dev)<br/><sup>By **[kamaravichow](https://github.com/kamaravichow)** on **2023-12-25**</sup> | 一位精通 Flutter 框架和 Dart 编程语言的开发者<br/>`flutter` `development` `dart` `programming` `widgets` |
193
-
194
- > 📊 Total agents: [<kbd>**81**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
187
+ | 最近新增 | 助手说明 |
188
+ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------- |
189
+ | [部署专家代理](https://chat-preview.lobehub.com/market?agent=deployment-agent)<br/><sup>By **[amitalokbera](https://github.com/amitalokbera)** on **2023-12-27**</sup> | AI 部署专家是管理软件应用的完整部署生命周期的专家,特别是 Web 应用。<br/>`代码` `部署` `容器化` |
190
+ | [美术论文概述专家](https://chat-preview.lobehub.com/market?agent=thesis-overview)<br/><sup>By **[caoyang2002](https://github.com/caoyang2002)** on **2023-12-27**</sup> | 擅长论文简述与美术评论<br/>`美术` `论文` `评论` |
191
+ | [美式英语转译专家](https://chat-preview.lobehub.com/market?agent=to-local-english)<br/><sup>By **[doresu](https://github.com/doresu)** on **2023-12-27**</sup> | 粗鲁老编辑、资深作家和翻译家,擅长直译英文并转化为地道的美式英语<br/>`翻译` `编辑` `写作` `翻译家` |
192
+ | [学术润色专家](https://chat-preview.lobehub.com/market?agent=academic-paragraph-refiner)<br/><sup>By **[Feliks151450](https://github.com/Feliks151450)** on **2023-12-26**</sup> | 高级研究校对及语言编辑,专业于多个研究领域,精通学术英语。<br/>`校对` `写作` `研究` |
193
+
194
+ > 📊 Total agents: [<kbd>**82**</kbd> ](https://github.com/lobehub/lobe-chat-agents)
195
195
 
196
196
  <!-- AGENT LIST -->
197
197
 
@@ -16,7 +16,7 @@ LobeChat provides additional configuration options during deployment, which can
16
16
  - [`AZURE_API_VERSION`](#azure_api_version)
17
17
  - [Plugin Service](#plugin-service)
18
18
  - [`PLUGINS_INDEX_URL`](#plugins_index_url)
19
- - [`PLUGINS_SETTINGS`](#plugins_settings)
19
+ - [`PLUGIN_SETTINGS`](#plugin_settings)
20
20
  - [Agent Service](#agent-service)
21
21
  - [`AGENTS_INDEX_URL`](#agents_index_url)
22
22
  - [Data Analytics](#data-analytics)
@@ -94,7 +94,7 @@ If you need to use Azure OpenAI to provide model services, you can refer to the
94
94
  - Description: The index address of the LobeChat plugin market. If you have deployed the plugin market service yourself, you can use this variable to override the default plugin market address
95
95
  - Default: `https://chat-plugins.lobehub.com`
96
96
 
97
- ### `PLUGINS_SETTINGS`
97
+ ### `PLUGIN_SETTINGS`
98
98
 
99
99
  - Type: Optional
100
100
  - Description: Used to set the plugin settings, the format is `plugin-identifier:key1=value1;key2=value2`, multiple settings fields are separated by semicolons `;`, multiple plugin settings are separated by commas `,`.
@@ -16,7 +16,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
16
16
  - [`AZURE_API_VERSION`](#azure_api_version)
17
17
  - [插件服务](#插件服务)
18
18
  - [`PLUGINS_INDEX_URL`](#plugins_index_url)
19
- - [`PLUGINS_SETTINGS`](#plugins_settings)
19
+ - [`PLUGIN_SETTINGS`](#plugin_settings)
20
20
  - [角色服务](#角色服务)
21
21
  - [`AGENTS_INDEX_URL`](#agents_index_url)
22
22
  - [数据统计](#数据统计)
@@ -92,7 +92,7 @@ LobeChat 在部署时提供了一些额外的配置项,使用环境变量进
92
92
  - 描述:LobeChat 插件市场的索引地址,如果你自行部署了插件市场的服务,可以使用该变量来覆盖默认的插件市场地址
93
93
  - 默认值:`https://chat-plugins.lobehub.com`
94
94
 
95
- ### `PLUGINS_SETTINGS`
95
+ ### `PLUGIN_SETTINGS`
96
96
 
97
97
  - 类型:可选
98
98
  - 描述:用于配置插件的设置,使用 `插件名:设置字段=设置值` 的格式来配置插件的设置,多个设置字段用英文分号 `;` 隔开,多个插件设置使用英文逗号`,`隔开。
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.117.1",
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",
@@ -0,0 +1,54 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { AgentMarket } from './AgentMarket';
4
+
5
+ const baseURL = 'https://chat-agents.lobehub.com';
6
+ describe('AgentMarket', () => {
7
+ it('should return the default index URL when no language is provided', () => {
8
+ const agentMarket = new AgentMarket();
9
+ const url = agentMarket.getAgentIndexUrl();
10
+ expect(url).toBe(baseURL);
11
+ });
12
+
13
+ it('should return the index URL for a supported language', () => {
14
+ const agentMarket = new AgentMarket();
15
+ const url = agentMarket.getAgentIndexUrl('ko-KR');
16
+ expect(url).toBe('https://chat-agents.lobehub.com/index.ko-KR.json');
17
+ });
18
+
19
+ it('should return the zh-CN URL for zh locale', () => {
20
+ const agentMarket = new AgentMarket();
21
+ const url = agentMarket.getAgentIndexUrl('zh' as any);
22
+ expect(url).toBe('https://chat-agents.lobehub.com/index.zh-CN.json');
23
+ });
24
+
25
+ it('should return the default URL for en locale', () => {
26
+ const agentMarket = new AgentMarket();
27
+ const url = agentMarket.getAgentIndexUrl('en' as any);
28
+ expect(url).toBe('https://chat-agents.lobehub.com');
29
+ });
30
+
31
+ it('should return the base URL if the provided language is not supported', () => {
32
+ const agentMarket = new AgentMarket();
33
+ const url = agentMarket.getAgentIndexUrl('fr' as any);
34
+ expect(url).toBe(baseURL);
35
+ });
36
+
37
+ it('should return the agent URL with default language when no language is provided', () => {
38
+ const agentMarket = new AgentMarket();
39
+ const url = agentMarket.getAgentUrl('agent-123');
40
+ expect(url).toBe(`${baseURL}/agent-123.json`);
41
+ });
42
+
43
+ it('should return the agent URL for a supported language', () => {
44
+ const agentMarket = new AgentMarket();
45
+ const url = agentMarket.getAgentUrl('agent-123', 'es-ES');
46
+ expect(url).toBe(`${baseURL}/agent-123.es-ES.json`);
47
+ });
48
+
49
+ it('should return the agent URL without language suffix if the provided language is not supported', () => {
50
+ const agentMarket = new AgentMarket();
51
+ const url = agentMarket.getAgentUrl('agent-123', 'fr' as any);
52
+ expect(url).toBe(`${baseURL}/agent-123.json`);
53
+ });
54
+ });
@@ -1,8 +1,8 @@
1
1
  import urlJoin from 'url-join';
2
2
 
3
3
  import { getServerConfig } from '@/config/server';
4
- import { DEFAULT_LANG, checkLang } from '@/const/locale';
5
- import { Locales } from '@/locales/resources';
4
+ import { DEFAULT_LANG, isLocaleNotSupport } from '@/const/locale';
5
+ import { Locales, normalizeLocale } from '@/locales/resources';
6
6
 
7
7
  export class AgentMarket {
8
8
  private readonly baseUrl: string;
@@ -12,14 +12,14 @@ export class AgentMarket {
12
12
  }
13
13
 
14
14
  getAgentIndexUrl = (lang: Locales = DEFAULT_LANG) => {
15
- if (checkLang(lang)) return this.baseUrl;
15
+ if (isLocaleNotSupport(lang)) return this.baseUrl;
16
16
 
17
- return urlJoin(this.baseUrl, `index.${lang}.json`);
17
+ return urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`);
18
18
  };
19
19
 
20
20
  getAgentUrl = (identifier: string, lang: Locales = DEFAULT_LANG) => {
21
- if (checkLang(lang)) return urlJoin(this.baseUrl, `${identifier}.json`);
21
+ if (isLocaleNotSupport(lang)) return urlJoin(this.baseUrl, `${identifier}.json`);
22
22
 
23
- return urlJoin(this.baseUrl, `${identifier}.${lang}.json`);
23
+ return urlJoin(this.baseUrl, `${identifier}.${normalizeLocale(lang)}.json`);
24
24
  };
25
25
  }
@@ -0,0 +1,27 @@
1
+ import { describe, expect, it, vi } from 'vitest';
2
+
3
+ import { isLocaleNotSupport } from '@/const/locale';
4
+
5
+ import { PluginStore } from './Store';
6
+
7
+ const baseURL = 'https://chat-plugins.lobehub.com';
8
+
9
+ describe('PluginStore', () => {
10
+ it('should return the default index URL when no language is provided', () => {
11
+ const pluginStore = new PluginStore();
12
+ const url = pluginStore.getPluginIndexUrl();
13
+ expect(url).toBe(baseURL);
14
+ });
15
+
16
+ it('should return the index URL for a supported language', () => {
17
+ const pluginStore = new PluginStore();
18
+ const url = pluginStore.getPluginIndexUrl('en-US');
19
+ expect(url).toBe(baseURL);
20
+ });
21
+
22
+ it('should return the base URL if the provided language is not supported', () => {
23
+ const pluginStore = new PluginStore();
24
+ const url = pluginStore.getPluginIndexUrl('fr-FR');
25
+ expect(url).toBe(`${baseURL}/index.fr-FR.json`);
26
+ });
27
+ });
@@ -1,8 +1,8 @@
1
1
  import urlJoin from 'url-join';
2
2
 
3
3
  import { getServerConfig } from '@/config/server';
4
- import { DEFAULT_LANG, checkLang } from '@/const/locale';
5
- import { Locales } from '@/locales/resources';
4
+ import { DEFAULT_LANG, isLocaleNotSupport } from '@/const/locale';
5
+ import { Locales, normalizeLocale } from '@/locales/resources';
6
6
 
7
7
  export class PluginStore {
8
8
  private readonly baseUrl: string;
@@ -12,8 +12,8 @@ export class PluginStore {
12
12
  }
13
13
 
14
14
  getPluginIndexUrl = (lang: Locales = DEFAULT_LANG) => {
15
- if (checkLang(lang)) return this.baseUrl;
15
+ if (isLocaleNotSupport(lang)) return this.baseUrl;
16
16
 
17
- return urlJoin(this.baseUrl, `index.${lang}.json`);
17
+ return urlJoin(this.baseUrl, `index.${normalizeLocale(lang)}.json`);
18
18
  };
19
19
  }
@@ -9,7 +9,7 @@ import { useTranslation } from 'react-i18next';
9
9
  import { FORM_STYLE } from '@/const/layoutTokens';
10
10
  import { DEFAULT_SETTINGS } from '@/const/settings';
11
11
  import AvatarWithUpload from '@/features/AvatarWithUpload';
12
- import { localeOptions } from '@/locales/options';
12
+ import { localeOptions } from '@/locales/resources';
13
13
  import { useChatStore } from '@/store/chat';
14
14
  import { useFileStore } from '@/store/file';
15
15
  import { useGlobalStore } from '@/store/global';
@@ -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
+ };
@@ -1,9 +1,12 @@
1
- import { localeOptions } from '@/locales/options';
2
- import { Locales } from '@/locales/resources';
1
+ import { Locales, normalizeLocale, supportLocales } from '@/locales/resources';
3
2
 
4
3
  export const DEFAULT_LANG = 'en-US';
5
4
  export const LOBE_LOCALE_COOKIE = 'LOBE_LOCALE';
6
5
 
7
- export const checkLang = (lang: Locales) => {
8
- return lang === DEFAULT_LANG || !localeOptions.map((o) => o.value).includes(lang);
6
+ /**
7
+ * Check if the language is supported
8
+ * @param locale
9
+ */
10
+ export const isLocaleNotSupport = (locale: Locales) => {
11
+ return normalizeLocale(locale) === DEFAULT_LANG || !supportLocales.includes(locale);
9
12
  };
@@ -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';
@@ -2,7 +2,7 @@ import { ActionIconGroupItems } from '@lobehub/ui/es/ActionIconGroup';
2
2
  import { LanguagesIcon, Play } from 'lucide-react';
3
3
  import { useTranslation } from 'react-i18next';
4
4
 
5
- import { localeOptions } from '@/locales/options';
5
+ import { localeOptions } from '@/locales/resources';
6
6
 
7
7
  export const useCustomActions = () => {
8
8
  const { t } = useTranslation('chat');
@@ -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 }) => {
@@ -6,6 +6,7 @@ import { initReactI18next } from 'react-i18next';
6
6
  import { getClientConfig } from '@/config/client';
7
7
  import { DEFAULT_LANG, LOBE_LOCALE_COOKIE } from '@/const/locale';
8
8
  import { COOKIE_CACHE_DAYS } from '@/const/settings';
9
+ import { normalizeLocale } from '@/locales/resources';
9
10
  import { isDev, isOnServerSide } from '@/utils/env';
10
11
 
11
12
  const { I18N_DEBUG, I18N_DEBUG_BROWSER, I18N_DEBUG_SERVER } = getClientConfig();
@@ -17,22 +18,9 @@ export const createI18nNext = (lang?: string) => {
17
18
  .use(LanguageDetector)
18
19
  .use(
19
20
  resourcesToBackend(async (lng: string, ns: string) => {
20
- switch (lng) {
21
- case 'zh-CN':
22
- case 'zh': {
23
- if (isDev) return import(`./default/${ns}`);
21
+ if (isDev && lng === 'zh-CN') return import(`./default/${ns}`);
24
22
 
25
- return import(`@/../locales/zh-CN/${ns}.json`);
26
- }
27
-
28
- case 'en': {
29
- return import(`@/../locales/en-US/${ns}.json`);
30
- }
31
-
32
- default: {
33
- return import(`@/../locales/${lng}/${ns}.json`);
34
- }
35
- }
23
+ return import(`@/../locales/${normalizeLocale(lng)}/${ns}.json`);
36
24
  }),
37
25
  );
38
26
 
@@ -16,3 +16,86 @@ export const locales = [
16
16
 
17
17
  export type DefaultResources = typeof resources;
18
18
  export type Locales = (typeof locales)[number];
19
+
20
+ export const normalizeLocale = (locale: string) => {
21
+ switch (locale) {
22
+ case 'zh-CN':
23
+ case 'zh': {
24
+ return 'zh-CN';
25
+ }
26
+
27
+ case 'en': {
28
+ return 'en-US';
29
+ }
30
+
31
+ default: {
32
+ return locale;
33
+ }
34
+ }
35
+ };
36
+
37
+ type LocaleOptions = {
38
+ label: string;
39
+ value: Locales;
40
+ }[];
41
+
42
+ export const localeOptions: LocaleOptions = [
43
+ {
44
+ label: '简体中文',
45
+ value: 'zh-CN',
46
+ },
47
+ {
48
+ label: '繁體中文',
49
+ value: 'zh-TW',
50
+ },
51
+ {
52
+ label: 'English',
53
+ value: 'en-US',
54
+ },
55
+ {
56
+ label: '日本語',
57
+ value: 'ja-JP',
58
+ },
59
+ {
60
+ label: '한국어',
61
+ value: 'ko-KR',
62
+ },
63
+ {
64
+ label: 'Deutsch',
65
+ value: 'de-DE',
66
+ },
67
+ {
68
+ label: 'Español',
69
+ value: 'es-ES',
70
+ },
71
+ {
72
+ label: 'Français',
73
+ value: 'fr-FR',
74
+ },
75
+ {
76
+ label: 'Português',
77
+ value: 'pt-BR',
78
+ },
79
+ {
80
+ label: 'Русский',
81
+ value: 'ru-RU',
82
+ },
83
+ {
84
+ label: 'Türkçe',
85
+ value: 'tr-TR',
86
+ },
87
+ {
88
+ label: 'Polski',
89
+ value: 'pl-PL',
90
+ },
91
+ {
92
+ label: 'Nederlands',
93
+ value: 'nl-NL',
94
+ },
95
+ {
96
+ label: 'Italiano',
97
+ value: 'it-IT',
98
+ },
99
+ ] as LocaleOptions;
100
+
101
+ export const supportLocales: string[] = [...locales, 'en', 'zh'];
@@ -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
  }
@@ -4,7 +4,7 @@ import { StateCreator } from 'zustand/vanilla';
4
4
 
5
5
  import { chainLangDetect } from '@/chains/langDetect';
6
6
  import { chainTranslate } from '@/chains/translate';
7
- import { supportLocales } from '@/locales/options';
7
+ import { supportLocales } from '@/locales/resources';
8
8
  import { chatService } from '@/services/chat';
9
9
  import { fileService } from '@/services/file';
10
10
  import { imageGenerationService } from '@/services/imageGeneration';
@@ -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,69 +0,0 @@
1
- import type { Locales } from '@/types/locale';
2
-
3
- import { locales } from './resources';
4
-
5
- type LocaleOptions = {
6
- label: string;
7
- value: Locales;
8
- }[];
9
-
10
- export const localeOptions: LocaleOptions = [
11
- {
12
- label: '简体中文',
13
- value: 'zh-CN',
14
- },
15
- {
16
- label: '繁體中文',
17
- value: 'zh-TW',
18
- },
19
- {
20
- label: 'English',
21
- value: 'en-US',
22
- },
23
- {
24
- label: '日本語',
25
- value: 'ja-JP',
26
- },
27
- {
28
- label: '한국어',
29
- value: 'ko-KR',
30
- },
31
- {
32
- label: 'Deutsch',
33
- value: 'de-DE',
34
- },
35
- {
36
- label: 'Español',
37
- value: 'es-ES',
38
- },
39
- {
40
- label: 'Français',
41
- value: 'fr-FR',
42
- },
43
- {
44
- label: 'Português',
45
- value: 'pt-BR',
46
- },
47
- {
48
- label: 'Русский',
49
- value: 'ru-RU',
50
- },
51
- {
52
- label: 'Türkçe',
53
- value: 'tr-TR',
54
- },
55
- {
56
- label: 'Polski',
57
- value: 'pl-PL',
58
- },
59
- {
60
- label: 'Nederlands',
61
- value: 'nl-NL',
62
- },
63
- {
64
- label: 'Italiano',
65
- value: 'it-IT',
66
- },
67
- ] as LocaleOptions;
68
-
69
- export const supportLocales: string[] = [...locales, 'en', 'zh'];
@@ -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
- // };