@lobehub/chat 1.0.13 → 1.0.14
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 +25 -0
- package/README.md +16 -14
- package/README.zh-CN.md +16 -14
- package/docs/self-hosting/advanced/feature-flags.zh-CN.mdx +2 -1
- package/docs/self-hosting/advanced/model-list.zh-CN.mdx +1 -0
- package/docs/self-hosting/advanced/server-database.mdx +4 -3
- package/docs/self-hosting/advanced/server-database.zh-CN.mdx +1 -0
- package/docs/self-hosting/advanced/settings-url-share.mdx +5 -4
- package/docs/self-hosting/advanced/settings-url-share.zh-CN.mdx +5 -4
- package/docs/self-hosting/advanced/sso-providers/zitadel.mdx +3 -3
- package/docs/self-hosting/advanced/sso-providers/zitadel.zh-CN.mdx +2 -1
- package/docs/self-hosting/advanced/upstream-sync.zh-CN.mdx +10 -10
- package/docs/self-hosting/examples/ollama.mdx +23 -23
- package/docs/self-hosting/examples/ollama.zh-CN.mdx +23 -24
- package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +2 -3
- package/docs/self-hosting/platform/vercel.mdx +2 -2
- package/docs/self-hosting/platform/vercel.zh-CN.mdx +2 -1
- package/docs/self-hosting/platform/zeabur.mdx +6 -7
- package/docs/self-hosting/platform/zeabur.zh-CN.mdx +6 -7
- package/docs/usage/agents/prompt.mdx +1 -1
- package/docs/usage/agents/prompt.zh-CN.mdx +1 -1
- package/docs/usage/features/auth.mdx +13 -8
- package/docs/usage/features/auth.zh-CN.mdx +5 -3
- package/docs/usage/features/database.mdx +20 -14
- package/docs/usage/features/database.zh-CN.mdx +1 -1
- package/docs/usage/features/local-llm.mdx +5 -0
- package/docs/usage/features/local-llm.zh-CN.mdx +5 -0
- package/docs/usage/features/multi-ai-providers.mdx +5 -0
- package/docs/usage/features/multi-ai-providers.zh-CN.mdx +5 -0
- package/docs/usage/features/plugin-system.zh-CN.mdx +2 -1
- package/docs/usage/features/pwa.mdx +3 -2
- package/docs/usage/features/pwa.zh-CN.mdx +3 -2
- package/docs/usage/providers/01ai.mdx +86 -0
- package/docs/usage/providers/01ai.zh-CN.mdx +85 -0
- package/docs/usage/providers/anthropic.mdx +79 -0
- package/docs/usage/providers/anthropic.zh-CN.mdx +74 -0
- package/docs/usage/providers/azure.mdx +89 -0
- package/docs/usage/providers/azure.zh-CN.mdx +82 -0
- package/docs/usage/providers/bedrock.mdx +140 -0
- package/docs/usage/providers/bedrock.zh-CN.mdx +135 -0
- package/docs/usage/providers/deepseek.mdx +91 -0
- package/docs/usage/providers/deepseek.zh-CN.mdx +86 -0
- package/docs/usage/providers/gemini.mdx +83 -0
- package/docs/usage/providers/gemini.zh-CN.mdx +80 -0
- package/docs/usage/providers/groq.mdx +1 -3
- package/docs/usage/providers/groq.zh-CN.mdx +1 -1
- package/docs/usage/providers/minimax.mdx +89 -0
- package/docs/usage/providers/minimax.zh-CN.mdx +85 -0
- package/docs/usage/providers/mistral.mdx +71 -0
- package/docs/usage/providers/mistral.zh-CN.mdx +66 -0
- package/docs/usage/providers/moonshot.mdx +70 -0
- package/docs/usage/providers/moonshot.zh-CN.mdx +66 -0
- package/docs/usage/providers/ollama/gemma.mdx +1 -1
- package/docs/usage/providers/ollama/gemma.zh-CN.mdx +1 -1
- package/docs/usage/providers/ollama/qwen.mdx +1 -1
- package/docs/usage/providers/ollama/qwen.zh-CN.mdx +1 -1
- package/docs/usage/providers/ollama.mdx +1 -1
- package/docs/usage/providers/ollama.zh-CN.mdx +1 -1
- package/docs/usage/providers/openai.mdx +95 -0
- package/docs/usage/providers/openai.zh-CN.mdx +87 -0
- package/docs/usage/providers/openrouter.mdx +111 -0
- package/docs/usage/providers/openrouter.zh-CN.mdx +109 -0
- package/docs/usage/providers/perplexity.mdx +64 -0
- package/docs/usage/providers/perplexity.zh-CN.mdx +61 -0
- package/docs/usage/providers/qwen.mdx +93 -0
- package/docs/usage/providers/qwen.zh-CN.mdx +86 -0
- package/docs/usage/providers/stepfun.mdx +69 -0
- package/docs/usage/providers/stepfun.zh-CN.mdx +64 -0
- package/docs/usage/providers/togetherai.mdx +74 -0
- package/docs/usage/providers/togetherai.zh-CN.mdx +71 -0
- package/docs/usage/providers/zhipu.mdx +69 -0
- package/docs/usage/providers/zhipu.zh-CN.mdx +64 -0
- package/docs/usage/providers.mdx +36 -0
- package/docs/usage/providers.zh-CN.mdx +34 -0
- package/docs/usage/start.mdx +2 -0
- package/docs/usage/start.zh-CN.mdx +2 -0
- package/locales/ar/setting.json +1 -0
- package/locales/bg-BG/setting.json +1 -0
- package/locales/de-DE/setting.json +1 -0
- package/locales/en-US/setting.json +1 -0
- package/locales/es-ES/setting.json +1 -0
- package/locales/fr-FR/setting.json +1 -0
- package/locales/it-IT/setting.json +1 -0
- package/locales/ja-JP/setting.json +1 -0
- package/locales/ko-KR/setting.json +1 -0
- package/locales/nl-NL/setting.json +1 -0
- package/locales/pl-PL/setting.json +1 -0
- package/locales/pt-BR/setting.json +1 -0
- package/locales/ru-RU/setting.json +1 -0
- package/locales/tr-TR/setting.json +1 -0
- package/locales/vi-VN/setting.json +1 -0
- package/locales/zh-CN/setting.json +1 -0
- package/locales/zh-TW/setting.json +1 -0
- package/package.json +6 -5
- package/src/app/(main)/settings/llm/ProviderList/providers.tsx +33 -4
- package/src/app/(main)/settings/llm/components/ProviderConfig/index.tsx +41 -11
- package/src/app/(main)/settings/llm/index.tsx +1 -2
- package/src/features/ChatInput/useSend.ts +2 -1
- package/src/features/Conversation/Messages/Assistant/ToolCalls/index.tsx +1 -1
- package/src/features/Conversation/Messages/components/Arguments.tsx +5 -3
- package/src/features/Conversation/Messages/hooks/useYamlArguments.ts +5 -2
- package/src/locales/default/setting.ts +1 -0
- package/src/store/chat/slices/plugin/action.test.ts +5 -5
- package/src/store/chat/slices/plugin/action.ts +6 -2
- package/src/store/tool/slices/builtin/action.test.ts +8 -11
- package/src/store/tool/slices/builtin/action.ts +9 -9
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Laatst bijgewerkt: {{time}}",
|
|
103
103
|
"noLatestTime": "Geen lijst beschikbaar op dit moment"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "configuratiehandleiding",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Selecteer het model dat in de sessie moet worden weergegeven. Het geselecteerde model wordt weergegeven in de modellijst.",
|
|
107
108
|
"placeholder": "Selecteer een model uit de lijst",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Ostatnia aktualizacja: {{time}}",
|
|
103
103
|
"noLatestTime": "Brak dostępnej listy"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "Poradnik konfiguracji",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Wybierz modele do wyświetlenia w sesji. Wybrane modele będą widoczne na liście modeli",
|
|
107
108
|
"placeholder": "Wybierz model z listy",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Última atualização: {{time}}",
|
|
103
103
|
"noLatestTime": "Lista não disponível"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "Tutorial de configuração",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Escolha os modelos a serem exibidos na conversa. Os modelos selecionados serão exibidos na lista de modelos.",
|
|
107
108
|
"placeholder": "Selecione um modelo da lista",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Последнее обновление: {{time}}",
|
|
103
103
|
"noLatestTime": "Список пока не получен"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "Руководство по настройке",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Выберите модель для отображения в сеансе, выбранная модель будет отображаться в списке моделей",
|
|
107
108
|
"placeholder": "Выберите модель из списка",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Son güncelleme zamanı: {{time}}",
|
|
103
103
|
"noLatestTime": "Liste henüz alınamadı"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "Yardım Belgeleri",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Görüntülenecek modeli seçin, seçilen model model listesinde görüntülenecektir",
|
|
107
108
|
"placeholder": "Lütfen listeden bir model seçin",
|
|
@@ -102,6 +102,7 @@
|
|
|
102
102
|
"latestTime": "Thời gian cập nhật lần cuối: {{time}}",
|
|
103
103
|
"noLatestTime": "Chưa có danh sách nào được lấy"
|
|
104
104
|
},
|
|
105
|
+
"helpDoc": "Hướng dẫn cấu hình",
|
|
105
106
|
"modelList": {
|
|
106
107
|
"desc": "Chọn mô hình hiển thị trong cuộc trò chuyện, mô hình đã chọn sẽ được hiển thị trong danh sách mô hình",
|
|
107
108
|
"placeholder": "Vui lòng chọn mô hình từ danh sách",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.14",
|
|
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",
|
|
@@ -40,13 +40,13 @@
|
|
|
40
40
|
"db:z-pull": "drizzle-kit introspect -- dotenv_config_path='.env'",
|
|
41
41
|
"dev": "next dev -p 3010",
|
|
42
42
|
"dev:clerk-proxy": "ngrok http http://localhost:3011",
|
|
43
|
-
"docs:i18n": "lobe-i18n md && npm run
|
|
44
|
-
"docs:seo": "lobe-seo && npm run
|
|
43
|
+
"docs:i18n": "lobe-i18n md && npm run lint:mdx",
|
|
44
|
+
"docs:seo": "lobe-seo && npm run lint:mdx",
|
|
45
45
|
"i18n": "npm run workflow:i18n && lobe-i18n",
|
|
46
46
|
"lint": "npm run lint:ts && npm run lint:style && npm run type-check && npm run lint:circular",
|
|
47
47
|
"lint:circular": "dpdm src/**/*.ts --warning false --tree false --exit-code circular:1 -T true --skip-dynamic-imports circular",
|
|
48
48
|
"lint:md": "remark . --quiet --frail --output",
|
|
49
|
-
"lint:mdx": "
|
|
49
|
+
"lint:mdx": "npm run workflow:mdx-with-lint && prettier -c --write \"{src,docs}/**/*.mdx\" && npm run workflow:mdx-with-lint",
|
|
50
50
|
"lint:style": "stylelint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
|
|
51
51
|
"lint:ts": "eslint \"{src,tests}/**/*.{js,jsx,ts,tsx}\" --fix",
|
|
52
52
|
"prepare": "husky",
|
|
@@ -64,7 +64,8 @@
|
|
|
64
64
|
"type-check": "tsc --noEmit",
|
|
65
65
|
"workflow:docs": "tsx scripts/docsWorkflow/index.ts",
|
|
66
66
|
"workflow:i18n": "tsx scripts/i18nWorkflow/index.ts",
|
|
67
|
-
"workflow:mdx": "tsx scripts/mdxWorkflow/index.ts",
|
|
67
|
+
"workflow:mdx": "tsx ./scripts/mdxWorkflow/index.ts",
|
|
68
|
+
"workflow:mdx-with-lint": "tsx ./scripts/mdxWorkflow/index.ts && eslint \"docs/**/*.mdx\" --quiet --fix",
|
|
68
69
|
"workflow:readme": "tsx scripts/readmeWorkflow/index.ts"
|
|
69
70
|
},
|
|
70
71
|
"lint-staged": {
|
|
@@ -20,6 +20,7 @@ import { Divider } from 'antd';
|
|
|
20
20
|
import { useTheme } from 'antd-style';
|
|
21
21
|
import { useMemo } from 'react';
|
|
22
22
|
import { Flexbox } from 'react-layout-kit';
|
|
23
|
+
import urlJoin from 'url-join';
|
|
23
24
|
|
|
24
25
|
import {
|
|
25
26
|
AnthropicProviderCard,
|
|
@@ -44,6 +45,8 @@ import { useBedrockProvider } from './Bedrock';
|
|
|
44
45
|
import { useOllamaProvider } from './Ollama';
|
|
45
46
|
import { useOpenAIProvider } from './OpenAI';
|
|
46
47
|
|
|
48
|
+
const BASE_DOC_URL = 'https://lobehub.com/docs/usage/providers';
|
|
49
|
+
|
|
47
50
|
const AnthropicBrand = () => {
|
|
48
51
|
const { isDarkMode } = useTheme();
|
|
49
52
|
return <Anthropic.Text color={isDarkMode ? undefined : Claude.colorPrimary} size={15} />;
|
|
@@ -81,64 +84,90 @@ export const useProviderList = (): ProviderItem[] => {
|
|
|
81
84
|
|
|
82
85
|
return useMemo(
|
|
83
86
|
() => [
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
+
{
|
|
88
|
+
...openAIProvider,
|
|
89
|
+
docUrl: urlJoin(BASE_DOC_URL, 'openai'),
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
...ollamaProvider,
|
|
93
|
+
docUrl: urlJoin(BASE_DOC_URL, 'ollama'),
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
...azureProvider,
|
|
97
|
+
docUrl: urlJoin(BASE_DOC_URL, 'azure'),
|
|
98
|
+
},
|
|
87
99
|
{
|
|
88
100
|
...GoogleProviderCard,
|
|
101
|
+
docUrl: urlJoin(BASE_DOC_URL, 'gemini'),
|
|
89
102
|
title: <GoogleBrand />,
|
|
90
103
|
},
|
|
91
104
|
{
|
|
92
105
|
...AnthropicProviderCard,
|
|
106
|
+
docUrl: urlJoin(BASE_DOC_URL, 'anthropic'),
|
|
93
107
|
title: <AnthropicBrand />,
|
|
94
108
|
},
|
|
95
|
-
|
|
109
|
+
{
|
|
110
|
+
...bedrockProvider,
|
|
111
|
+
docUrl: urlJoin(BASE_DOC_URL, 'bedrock'),
|
|
112
|
+
},
|
|
96
113
|
{
|
|
97
114
|
...GroqProviderCard,
|
|
115
|
+
docUrl: urlJoin(BASE_DOC_URL, 'groq'),
|
|
98
116
|
title: <GroqBrand />,
|
|
99
117
|
},
|
|
100
118
|
{
|
|
101
119
|
...OpenRouterProviderCard,
|
|
120
|
+
docUrl: urlJoin(BASE_DOC_URL, 'openrouter'),
|
|
102
121
|
title: <OpenRouter.Combine iconProps={{ color: OpenRouter.colorPrimary }} size={20} />,
|
|
103
122
|
},
|
|
104
123
|
{
|
|
105
124
|
...TogetherAIProviderCard,
|
|
125
|
+
docUrl: urlJoin(BASE_DOC_URL, 'togetherai'),
|
|
106
126
|
title: <Together.Combine size={26} type={'color'} />,
|
|
107
127
|
},
|
|
108
128
|
{
|
|
109
129
|
...QwenProviderCard,
|
|
130
|
+
docUrl: urlJoin(BASE_DOC_URL, 'qwen'),
|
|
110
131
|
title: <Tongyi.Combine extra={'千问'} size={26} type={'color'} />,
|
|
111
132
|
},
|
|
112
133
|
{
|
|
113
134
|
...DeepSeekProviderCard,
|
|
135
|
+
docUrl: urlJoin(BASE_DOC_URL, 'deepseek'),
|
|
114
136
|
title: <DeepSeek.Combine size={28} type={'color'} />,
|
|
115
137
|
},
|
|
116
138
|
{
|
|
117
139
|
...MinimaxProviderCard,
|
|
140
|
+
docUrl: urlJoin(BASE_DOC_URL, 'minimax'),
|
|
118
141
|
title: <Minimax.Combine size={32} type={'color'} />,
|
|
119
142
|
},
|
|
120
143
|
{
|
|
121
144
|
...MistralProviderCard,
|
|
145
|
+
docUrl: urlJoin(BASE_DOC_URL, 'mistral'),
|
|
122
146
|
title: <Mistral.Combine size={26} type={'color'} />,
|
|
123
147
|
},
|
|
124
148
|
{
|
|
125
149
|
...MoonshotProviderCard,
|
|
150
|
+
docUrl: urlJoin(BASE_DOC_URL, 'moonshot'),
|
|
126
151
|
title: <MoonshotBrand />,
|
|
127
152
|
},
|
|
128
153
|
{
|
|
129
154
|
...PerplexityProviderCard,
|
|
155
|
+
docUrl: urlJoin(BASE_DOC_URL, 'perplexity'),
|
|
130
156
|
title: <Perplexity.Combine size={24} type={'color'} />,
|
|
131
157
|
},
|
|
132
158
|
{
|
|
133
159
|
...ZhiPuProviderCard,
|
|
160
|
+
docUrl: urlJoin(BASE_DOC_URL, 'zhipu'),
|
|
134
161
|
title: <Zhipu.Combine size={32} type={'color'} />,
|
|
135
162
|
},
|
|
136
163
|
{
|
|
137
164
|
...ZeroOneProviderCard,
|
|
165
|
+
docUrl: urlJoin(BASE_DOC_URL, '01ai'),
|
|
138
166
|
title: <ZeroOne.Text size={20} />,
|
|
139
167
|
},
|
|
140
168
|
{
|
|
141
169
|
...StepfunProviderCard,
|
|
170
|
+
docUrl: urlJoin(BASE_DOC_URL, 'stepfun'),
|
|
142
171
|
title: <Stepfun.Combine size={20} type={'color'} />,
|
|
143
172
|
},
|
|
144
173
|
],
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
|
|
3
|
-
import { Form, type FormItemProps, type ItemGroup } from '@lobehub/ui';
|
|
3
|
+
import { Form, type FormItemProps, type ItemGroup, Tooltip } from '@lobehub/ui';
|
|
4
4
|
import { Input, Switch } from 'antd';
|
|
5
5
|
import { createStyles } from 'antd-style';
|
|
6
6
|
import { debounce } from 'lodash-es';
|
|
7
|
+
import Link from 'next/link';
|
|
7
8
|
import { ReactNode, memo } from 'react';
|
|
8
9
|
import { useTranslation } from 'react-i18next';
|
|
9
|
-
import { Flexbox } from 'react-layout-kit';
|
|
10
|
+
import { Center, Flexbox } from 'react-layout-kit';
|
|
10
11
|
|
|
11
12
|
import { useSyncSettings } from '@/app/(main)/settings/hooks/useSyncSettings';
|
|
12
13
|
import {
|
|
@@ -25,7 +26,7 @@ import { GlobalLLMProviderKey } from '@/types/user/settings';
|
|
|
25
26
|
import Checker from '../Checker';
|
|
26
27
|
import ProviderModelListSelect from '../ProviderModelList';
|
|
27
28
|
|
|
28
|
-
const useStyles = createStyles(({ css, prefixCls, responsive }) => ({
|
|
29
|
+
const useStyles = createStyles(({ css, prefixCls, responsive, token }) => ({
|
|
29
30
|
form: css`
|
|
30
31
|
.${prefixCls}-form-item-control:has(.${prefixCls}-input,.${prefixCls}-select) {
|
|
31
32
|
flex: none;
|
|
@@ -40,6 +41,19 @@ const useStyles = createStyles(({ css, prefixCls, responsive }) => ({
|
|
|
40
41
|
font-size: 12px;
|
|
41
42
|
}
|
|
42
43
|
`,
|
|
44
|
+
help: css`
|
|
45
|
+
font-size: 12px;
|
|
46
|
+
font-weight: 500;
|
|
47
|
+
color: ${token.colorTextDescription};
|
|
48
|
+
|
|
49
|
+
background: ${token.colorFillTertiary};
|
|
50
|
+
border-radius: 50%;
|
|
51
|
+
|
|
52
|
+
&:hover {
|
|
53
|
+
color: ${token.colorText};
|
|
54
|
+
background: ${token.colorFill};
|
|
55
|
+
}
|
|
56
|
+
`,
|
|
43
57
|
safariIconWidthFix: css`
|
|
44
58
|
svg {
|
|
45
59
|
width: unset !important;
|
|
@@ -52,6 +66,7 @@ export interface ProviderConfigProps extends Omit<ModelProviderCard, 'id'> {
|
|
|
52
66
|
canDeactivate?: boolean;
|
|
53
67
|
checkerItem?: FormItemProps;
|
|
54
68
|
className?: string;
|
|
69
|
+
docUrl?: string;
|
|
55
70
|
hideSwitch?: boolean;
|
|
56
71
|
id: GlobalLLMProviderKey;
|
|
57
72
|
modelList?: {
|
|
@@ -78,6 +93,7 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
|
|
78
93
|
disableBrowserRequest,
|
|
79
94
|
className,
|
|
80
95
|
name,
|
|
96
|
+
docUrl,
|
|
81
97
|
}) => {
|
|
82
98
|
const { t } = useTranslation('setting');
|
|
83
99
|
const [form] = Form.useForm();
|
|
@@ -178,14 +194,28 @@ const ProviderConfig = memo<ProviderConfigProps>(
|
|
|
178
194
|
children: formItems,
|
|
179
195
|
|
|
180
196
|
defaultActive: canDeactivate ? enabled : undefined,
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
197
|
+
|
|
198
|
+
extra: (
|
|
199
|
+
<Flexbox align={'center'} gap={8} horizontal>
|
|
200
|
+
{docUrl && (
|
|
201
|
+
<Tooltip title={t('llm.helpDoc')}>
|
|
202
|
+
<Link href={docUrl} onClick={(e) => e.stopPropagation()} target={'_blank'}>
|
|
203
|
+
<Center className={styles.help} height={20} width={20}>
|
|
204
|
+
?
|
|
205
|
+
</Center>
|
|
206
|
+
</Link>
|
|
207
|
+
</Tooltip>
|
|
208
|
+
)}
|
|
209
|
+
{canDeactivate ? (
|
|
210
|
+
<Switch
|
|
211
|
+
onChange={(enabled) => {
|
|
212
|
+
toggleProviderEnabled(id, enabled);
|
|
213
|
+
}}
|
|
214
|
+
value={enabled}
|
|
215
|
+
/>
|
|
216
|
+
) : undefined}
|
|
217
|
+
</Flexbox>
|
|
218
|
+
),
|
|
189
219
|
title: (
|
|
190
220
|
<Flexbox
|
|
191
221
|
align={'center'}
|
|
@@ -2,9 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
-
import Footer from '@/app/(main)/settings/llm/components/Footer';
|
|
6
|
-
|
|
7
5
|
import { useProviderList } from './ProviderList/providers';
|
|
6
|
+
import Footer from './components/Footer';
|
|
8
7
|
import ProviderConfig from './components/ProviderConfig';
|
|
9
8
|
|
|
10
9
|
const Page = () => {
|
|
@@ -19,9 +19,10 @@ export const useSendMessage = () => {
|
|
|
19
19
|
return useCallback((params: UseSendMessageParams = {}) => {
|
|
20
20
|
const store = useChatStore.getState();
|
|
21
21
|
if (chatSelectors.isAIGenerating(store)) return;
|
|
22
|
-
if (!store.inputMessage) return;
|
|
23
22
|
|
|
24
23
|
const imageList = filesSelectors.imageUrlOrBase64List(useFileStore.getState());
|
|
24
|
+
// if there is no message and no image, then we should not send the message
|
|
25
|
+
if (!store.inputMessage && imageList.length === 0) return;
|
|
25
26
|
|
|
26
27
|
sendMessage({
|
|
27
28
|
files: imageList,
|
|
@@ -22,7 +22,7 @@ export interface InspectorProps {
|
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
const CallItem = memo<InspectorProps>(
|
|
25
|
-
({ arguments: requestArgs
|
|
25
|
+
({ arguments: requestArgs, messageId, index, identifier, style }) => {
|
|
26
26
|
const { t } = useTranslation('plugin');
|
|
27
27
|
const { styles } = useStyles();
|
|
28
28
|
const [open, setOpen] = useState(false);
|
|
@@ -11,9 +11,11 @@ const Arguments = memo<ArgumentsProps>(({ arguments: args = '' }) => {
|
|
|
11
11
|
const yaml = useYamlArguments(args);
|
|
12
12
|
|
|
13
13
|
return (
|
|
14
|
-
|
|
15
|
-
{yaml}
|
|
16
|
-
|
|
14
|
+
!!yaml && (
|
|
15
|
+
<Highlighter language={'yaml'} showLanguage={false}>
|
|
16
|
+
{yaml}
|
|
17
|
+
</Highlighter>
|
|
18
|
+
)
|
|
17
19
|
);
|
|
18
20
|
});
|
|
19
21
|
|
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { parse } from 'partial-json';
|
|
2
2
|
import { stringify } from 'yaml';
|
|
3
3
|
|
|
4
4
|
export const useYamlArguments = (args: string) => {
|
|
5
5
|
try {
|
|
6
|
-
const obj = parse(args
|
|
6
|
+
const obj = parse(args);
|
|
7
|
+
|
|
8
|
+
if (Object.keys(obj).length === 0) return '';
|
|
9
|
+
|
|
7
10
|
return stringify(obj);
|
|
8
11
|
} catch {
|
|
9
12
|
return args;
|
|
@@ -463,7 +463,7 @@ describe('ChatPluginAction', () => {
|
|
|
463
463
|
const toolResponse = JSON.stringify({ abc: 'data' });
|
|
464
464
|
|
|
465
465
|
useToolStore.setState({
|
|
466
|
-
|
|
466
|
+
transformApiArgumentsToAiState: vi.fn().mockResolvedValue(toolResponse),
|
|
467
467
|
});
|
|
468
468
|
|
|
469
469
|
useChatStore.setState({
|
|
@@ -479,7 +479,7 @@ describe('ChatPluginAction', () => {
|
|
|
479
479
|
});
|
|
480
480
|
|
|
481
481
|
// Verify that the builtin tool was invoked with the correct arguments
|
|
482
|
-
expect(useToolStore.getState().
|
|
482
|
+
expect(useToolStore.getState().transformApiArgumentsToAiState).toHaveBeenCalledWith(
|
|
483
483
|
payload.apiName,
|
|
484
484
|
JSON.parse(payload.arguments),
|
|
485
485
|
);
|
|
@@ -511,7 +511,7 @@ describe('ChatPluginAction', () => {
|
|
|
511
511
|
|
|
512
512
|
act(() => {
|
|
513
513
|
useToolStore.setState({
|
|
514
|
-
|
|
514
|
+
transformApiArgumentsToAiState: vi.fn().mockResolvedValue(toolResponse),
|
|
515
515
|
text2image: vi.fn(),
|
|
516
516
|
});
|
|
517
517
|
|
|
@@ -528,7 +528,7 @@ describe('ChatPluginAction', () => {
|
|
|
528
528
|
});
|
|
529
529
|
|
|
530
530
|
// Verify that the builtin tool was invoked with the correct arguments
|
|
531
|
-
expect(useToolStore.getState().
|
|
531
|
+
expect(useToolStore.getState().transformApiArgumentsToAiState).toHaveBeenCalledWith(
|
|
532
532
|
payload.apiName,
|
|
533
533
|
JSON.parse(payload.arguments),
|
|
534
534
|
);
|
|
@@ -559,7 +559,7 @@ describe('ChatPluginAction', () => {
|
|
|
559
559
|
const error = new Error('Builtin tool failed');
|
|
560
560
|
|
|
561
561
|
useToolStore.setState({
|
|
562
|
-
|
|
562
|
+
transformApiArgumentsToAiState: vi.fn().mockRejectedValue(error),
|
|
563
563
|
});
|
|
564
564
|
|
|
565
565
|
useChatStore.setState({
|
|
@@ -81,7 +81,7 @@ export const chatPlugin: StateCreator<
|
|
|
81
81
|
internal_togglePluginApiCalling(true, id, n('invokeBuiltinTool') as string);
|
|
82
82
|
let data;
|
|
83
83
|
try {
|
|
84
|
-
data = await useToolStore.getState().
|
|
84
|
+
data = await useToolStore.getState().transformApiArgumentsToAiState(payload.apiName, params);
|
|
85
85
|
} catch (error) {
|
|
86
86
|
console.log(error);
|
|
87
87
|
}
|
|
@@ -91,6 +91,7 @@ export const chatPlugin: StateCreator<
|
|
|
91
91
|
|
|
92
92
|
await internal_updateMessageContent(id, data);
|
|
93
93
|
|
|
94
|
+
// run tool api call
|
|
94
95
|
// postToolCalling
|
|
95
96
|
// @ts-ignore
|
|
96
97
|
const { [payload.apiName]: action } = get();
|
|
@@ -147,7 +148,10 @@ export const chatPlugin: StateCreator<
|
|
|
147
148
|
const message = chatSelectors.getMessageById(id)(get());
|
|
148
149
|
if (!message || message.role !== 'tool' || !message.plugin) return;
|
|
149
150
|
|
|
150
|
-
|
|
151
|
+
// if there is error content, then clear the error
|
|
152
|
+
if (!!message.error) {
|
|
153
|
+
get().internal_updateMessageError(id, null);
|
|
154
|
+
}
|
|
151
155
|
|
|
152
156
|
const payload: ChatToolPayload = { ...message.plugin, id: message.tool_call_id! };
|
|
153
157
|
|
|
@@ -23,7 +23,7 @@ describe('createBuiltinToolSlice', () => {
|
|
|
23
23
|
|
|
24
24
|
await act(async () => {
|
|
25
25
|
// When
|
|
26
|
-
const data = await result.current.
|
|
26
|
+
const data = await result.current.transformApiArgumentsToAiState(key, params);
|
|
27
27
|
expect(data).toBeUndefined();
|
|
28
28
|
});
|
|
29
29
|
|
|
@@ -53,7 +53,7 @@ describe('createBuiltinToolSlice', () => {
|
|
|
53
53
|
});
|
|
54
54
|
// When
|
|
55
55
|
await act(async () => {
|
|
56
|
-
await result.current.
|
|
56
|
+
await result.current.transformApiArgumentsToAiState(key, params);
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
expect(mockFn).toBeCalledWith({
|
|
@@ -70,15 +70,12 @@ describe('createBuiltinToolSlice', () => {
|
|
|
70
70
|
// When
|
|
71
71
|
const { result } = renderHook(() => useToolStore());
|
|
72
72
|
|
|
73
|
-
const data = result.current.text2image(
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
},
|
|
80
|
-
'a',
|
|
81
|
-
);
|
|
73
|
+
const data = result.current.text2image({
|
|
74
|
+
prompts: ['prompt1', 'prompt2'],
|
|
75
|
+
size: '1024x1024',
|
|
76
|
+
quality: 'standard',
|
|
77
|
+
style: 'vivid',
|
|
78
|
+
});
|
|
82
79
|
|
|
83
80
|
// Then
|
|
84
81
|
expect(data).toEqual([
|
|
@@ -16,9 +16,9 @@ interface Text2ImageParams extends Pick<OpenAIImagePayload, 'quality' | 'style'
|
|
|
16
16
|
* 代理行为接口
|
|
17
17
|
*/
|
|
18
18
|
export interface BuiltinToolAction {
|
|
19
|
-
|
|
20
|
-
text2image: (params: Text2ImageParams, messageId: string) => DallEImageItem[];
|
|
19
|
+
text2image: (params: Text2ImageParams) => DallEImageItem[];
|
|
21
20
|
toggleBuiltinToolLoading: (key: string, value: boolean) => void;
|
|
21
|
+
transformApiArgumentsToAiState: (key: string, params: any) => Promise<string | undefined>;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
export const createBuiltinToolSlice: StateCreator<
|
|
@@ -27,7 +27,13 @@ export const createBuiltinToolSlice: StateCreator<
|
|
|
27
27
|
[],
|
|
28
28
|
BuiltinToolAction
|
|
29
29
|
> = (set, get) => ({
|
|
30
|
-
|
|
30
|
+
text2image: ({ prompts, size = '1024x1024' as const, quality = 'standard', style = 'vivid' }) =>
|
|
31
|
+
prompts.map((p) => ({ prompt: p, quality, size, style })),
|
|
32
|
+
toggleBuiltinToolLoading: (key, value) => {
|
|
33
|
+
set({ builtinToolLoading: { [key]: value } }, false, n('toggleBuiltinToolLoading'));
|
|
34
|
+
},
|
|
35
|
+
|
|
36
|
+
transformApiArgumentsToAiState: async (key, params) => {
|
|
31
37
|
const { builtinToolLoading, toggleBuiltinToolLoading } = get();
|
|
32
38
|
|
|
33
39
|
if (builtinToolLoading[key]) return;
|
|
@@ -45,10 +51,4 @@ export const createBuiltinToolSlice: StateCreator<
|
|
|
45
51
|
|
|
46
52
|
return JSON.stringify(result);
|
|
47
53
|
},
|
|
48
|
-
text2image: ({ prompts, size = '1024x1024' as const, quality = 'standard', style = 'vivid' }) =>
|
|
49
|
-
prompts.map((p) => ({ prompt: p, quality, size, style })),
|
|
50
|
-
|
|
51
|
-
toggleBuiltinToolLoading: (key, value) => {
|
|
52
|
-
set({ builtinToolLoading: { [key]: value } }, false, n('toggleBuiltinToolLoading'));
|
|
53
|
-
},
|
|
54
54
|
});
|