@lobehub/lobehub 2.0.0-next.52 → 2.0.0-next.54
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 +58 -0
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/apps/desktop/package.json +1 -1
- package/changelog/v1.json +21 -0
- package/package.json +2 -2
- package/packages/const/src/models.ts +2 -0
- package/packages/electron-server-ipc/src/ipcClient.ts +31 -31
- package/packages/electron-server-ipc/src/ipcServer.ts +15 -15
- package/packages/model-bank/src/aiModels/aihubmix.ts +106 -2
- package/packages/model-bank/src/aiModels/openai.ts +107 -3
- package/packages/model-bank/src/aiModels/qwen.ts +76 -7
- package/packages/model-bank/src/types/aiModel.ts +1 -0
- package/packages/types/src/agent/chatConfig.ts +9 -0
- package/src/app/[variants]/(main)/chat/components/WorkspaceLayout.tsx +32 -23
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +12 -0
- package/src/features/ChatInput/ActionBar/Model/GPT51ReasoningEffortSlider.tsx +58 -0
- package/src/features/ChatItem/components/MessageContent.tsx +3 -1
- package/src/features/Conversation/Messages/Assistant/index.tsx +7 -1
- package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ApprovalActions.tsx +34 -13
- package/src/features/Conversation/Messages/User/index.tsx +11 -1
- package/src/libs/mcp/__tests__/__snapshots__/index.test.ts.snap +0 -6
- package/src/locales/default/chat.ts +2 -0
- package/src/locales/default/tool.ts +8 -0
- package/src/services/chat/index.ts +7 -0
- package/src/store/chat/slices/aiChat/actions/conversationControl.ts +42 -0
- package/src/store/chat/slices/builtinTool/actions/localSystem.ts +1 -1
- package/src/tools/interventions.ts +3 -5
- package/src/tools/local-system/Intervention/MoveLocalFiles/MoveFileItem.tsx +56 -0
- package/src/tools/local-system/Intervention/MoveLocalFiles/index.tsx +26 -0
- package/src/tools/local-system/Intervention/RunCommand/index.tsx +3 -5
- package/src/tools/local-system/Intervention/index.ts +11 -0
- package/src/tools/local-system/Render/MoveLocalFiles/MoveFileItem.tsx +56 -0
- package/src/tools/local-system/Render/MoveLocalFiles/index.tsx +26 -0
- package/src/tools/local-system/Render/ReadLocalFile/ReadFileView.tsx +2 -1
- package/src/tools/local-system/Render/index.ts +21 -0
- package/src/tools/local-system/index.ts +1 -0
- package/src/tools/renders.ts +6 -24
- package/src/tools/web-browsing/Render/index.ts +13 -0
|
@@ -18,6 +18,112 @@ export const gptImage1ParamsSchema: ModelParamsSchema = {
|
|
|
18
18
|
};
|
|
19
19
|
|
|
20
20
|
export const openaiChatModels: AIChatModelCard[] = [
|
|
21
|
+
{
|
|
22
|
+
abilities: {
|
|
23
|
+
functionCall: true,
|
|
24
|
+
imageOutput: true,
|
|
25
|
+
reasoning: true,
|
|
26
|
+
search: true,
|
|
27
|
+
vision: true,
|
|
28
|
+
},
|
|
29
|
+
contextWindowTokens: 400_000,
|
|
30
|
+
description:
|
|
31
|
+
'GPT-5.1 — 针对编码和 agent 任务优化的旗舰模型,支持可配置的推理强度与更长上下文。',
|
|
32
|
+
displayName: 'GPT-5.1',
|
|
33
|
+
enabled: true,
|
|
34
|
+
id: 'gpt-5.1',
|
|
35
|
+
maxOutput: 128_000,
|
|
36
|
+
pricing: {
|
|
37
|
+
units: [
|
|
38
|
+
{ name: 'textInput', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
39
|
+
{ name: 'textInput_cacheRead', rate: 0.125, strategy: 'fixed', unit: 'millionTokens' },
|
|
40
|
+
{ name: 'textOutput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
|
|
41
|
+
],
|
|
42
|
+
},
|
|
43
|
+
releasedAt: '2025-11-13',
|
|
44
|
+
settings: {
|
|
45
|
+
extendParams: ['gpt5_1ReasoningEffort', 'textVerbosity'],
|
|
46
|
+
searchImpl: 'params',
|
|
47
|
+
},
|
|
48
|
+
type: 'chat',
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
abilities: {
|
|
52
|
+
functionCall: true,
|
|
53
|
+
vision: true,
|
|
54
|
+
},
|
|
55
|
+
contextWindowTokens: 128_000,
|
|
56
|
+
description: 'GPT-5.1 Chat:用于 ChatGPT 的 GPT-5.1 变体,适合聊天场景。',
|
|
57
|
+
displayName: 'GPT-5.1 Chat',
|
|
58
|
+
enabled: true,
|
|
59
|
+
id: 'gpt-5.1-chat-latest',
|
|
60
|
+
maxOutput: 16_384,
|
|
61
|
+
pricing: {
|
|
62
|
+
units: [
|
|
63
|
+
{ name: 'textInput', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
64
|
+
{ name: 'textInput_cacheRead', rate: 0.125, strategy: 'fixed', unit: 'millionTokens' },
|
|
65
|
+
{ name: 'textOutput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
releasedAt: '2025-11-13',
|
|
69
|
+
type: 'chat',
|
|
70
|
+
},
|
|
71
|
+
{
|
|
72
|
+
abilities: {
|
|
73
|
+
functionCall: true,
|
|
74
|
+
imageOutput: true,
|
|
75
|
+
reasoning: true,
|
|
76
|
+
search: true,
|
|
77
|
+
vision: true,
|
|
78
|
+
},
|
|
79
|
+
contextWindowTokens: 400_000,
|
|
80
|
+
description:
|
|
81
|
+
'GPT-5.1 Codex:针对 agentic 编码任务优化的 GPT-5.1 版本,可在 Responses API 中用于更复杂的代码/代理工作流。',
|
|
82
|
+
displayName: 'GPT-5.1 Codex',
|
|
83
|
+
id: 'gpt-5.1-codex',
|
|
84
|
+
maxOutput: 128_000,
|
|
85
|
+
pricing: {
|
|
86
|
+
units: [
|
|
87
|
+
{ name: 'textInput', rate: 1.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
88
|
+
{ name: 'textInput_cacheRead', rate: 0.125, strategy: 'fixed', unit: 'millionTokens' },
|
|
89
|
+
{ name: 'textOutput', rate: 10, strategy: 'fixed', unit: 'millionTokens' },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
releasedAt: '2025-11-13',
|
|
93
|
+
settings: {
|
|
94
|
+
extendParams: ['gpt5_1ReasoningEffort'],
|
|
95
|
+
searchImpl: 'params',
|
|
96
|
+
},
|
|
97
|
+
type: 'chat',
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
abilities: {
|
|
101
|
+
functionCall: true,
|
|
102
|
+
imageOutput: true,
|
|
103
|
+
reasoning: true,
|
|
104
|
+
search: true,
|
|
105
|
+
vision: true,
|
|
106
|
+
},
|
|
107
|
+
contextWindowTokens: 400_000,
|
|
108
|
+
description:
|
|
109
|
+
'GPT-5.1 Codex mini:体积更小、成本更低的 Codex 变体,针对 agentic 编码任务进行了优化。',
|
|
110
|
+
displayName: 'GPT-5.1 Codex mini',
|
|
111
|
+
id: 'gpt-5.1-codex-mini',
|
|
112
|
+
maxOutput: 128_000,
|
|
113
|
+
pricing: {
|
|
114
|
+
units: [
|
|
115
|
+
{ name: 'textInput', rate: 0.25, strategy: 'fixed', unit: 'millionTokens' },
|
|
116
|
+
{ name: 'textInput_cacheRead', rate: 0.025, strategy: 'fixed', unit: 'millionTokens' },
|
|
117
|
+
{ name: 'textOutput', rate: 2, strategy: 'fixed', unit: 'millionTokens' },
|
|
118
|
+
],
|
|
119
|
+
},
|
|
120
|
+
releasedAt: '2025-11-13',
|
|
121
|
+
settings: {
|
|
122
|
+
extendParams: ['gpt5_1ReasoningEffort'],
|
|
123
|
+
searchImpl: 'params',
|
|
124
|
+
},
|
|
125
|
+
type: 'chat',
|
|
126
|
+
},
|
|
21
127
|
{
|
|
22
128
|
abilities: {
|
|
23
129
|
functionCall: true,
|
|
@@ -64,7 +170,7 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
|
64
170
|
},
|
|
65
171
|
releasedAt: '2024-09-15',
|
|
66
172
|
settings: {
|
|
67
|
-
extendParams: ['gpt5ReasoningEffort'
|
|
173
|
+
extendParams: ['gpt5ReasoningEffort'],
|
|
68
174
|
searchImpl: 'params',
|
|
69
175
|
},
|
|
70
176
|
type: 'chat',
|
|
@@ -81,7 +187,6 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
|
81
187
|
description:
|
|
82
188
|
'跨领域编码和代理任务的最佳模型。GPT-5 在准确性、速度、推理、上下文识别、结构化思维和问题解决方面实现了飞跃。',
|
|
83
189
|
displayName: 'GPT-5',
|
|
84
|
-
enabled: true,
|
|
85
190
|
id: 'gpt-5',
|
|
86
191
|
maxOutput: 128_000,
|
|
87
192
|
pricing: {
|
|
@@ -159,7 +264,6 @@ export const openaiChatModels: AIChatModelCard[] = [
|
|
|
159
264
|
description:
|
|
160
265
|
'ChatGPT 中使用的 GPT-5 模型。结合了强大的语言理解与生成能力,适合对话式交互应用。',
|
|
161
266
|
displayName: 'GPT-5 Chat',
|
|
162
|
-
enabled: true,
|
|
163
267
|
id: 'gpt-5-chat-latest',
|
|
164
268
|
maxOutput: 128_000,
|
|
165
269
|
pricing: {
|
|
@@ -1016,6 +1016,71 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1016
1016
|
id: 'qwen3-max',
|
|
1017
1017
|
maxOutput: 65_536,
|
|
1018
1018
|
organization: 'Qwen',
|
|
1019
|
+
pricing: {
|
|
1020
|
+
currency: 'CNY',
|
|
1021
|
+
units: [
|
|
1022
|
+
{
|
|
1023
|
+
lookup: {
|
|
1024
|
+
prices: {
|
|
1025
|
+
'[0, 0.032]': 3.2 * 0.2,
|
|
1026
|
+
'[0.032, 0.128]': 6.4 * 0.2,
|
|
1027
|
+
'[0.128, infinity]': 9.6 * 0.2,
|
|
1028
|
+
},
|
|
1029
|
+
pricingParams: ['textInputRange'],
|
|
1030
|
+
},
|
|
1031
|
+
name: 'textInput_cacheRead',
|
|
1032
|
+
strategy: 'lookup',
|
|
1033
|
+
unit: 'millionTokens',
|
|
1034
|
+
},
|
|
1035
|
+
{
|
|
1036
|
+
lookup: {
|
|
1037
|
+
prices: {
|
|
1038
|
+
'[0, 0.032]': 3.2,
|
|
1039
|
+
'[0.032, 0.128]': 6.4,
|
|
1040
|
+
'[0.128, infinity]': 9.6,
|
|
1041
|
+
},
|
|
1042
|
+
pricingParams: ['textInputRange'],
|
|
1043
|
+
},
|
|
1044
|
+
name: 'textInput',
|
|
1045
|
+
strategy: 'lookup',
|
|
1046
|
+
unit: 'millionTokens',
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
lookup: {
|
|
1050
|
+
prices: {
|
|
1051
|
+
'[0, 0.032]': 12.8,
|
|
1052
|
+
'[0.032, 0.128]': 25.6,
|
|
1053
|
+
'[0.128, infinity]': 38.4,
|
|
1054
|
+
},
|
|
1055
|
+
pricingParams: ['textInputRange'],
|
|
1056
|
+
},
|
|
1057
|
+
name: 'textOutput',
|
|
1058
|
+
strategy: 'lookup',
|
|
1059
|
+
unit: 'millionTokens',
|
|
1060
|
+
},
|
|
1061
|
+
],
|
|
1062
|
+
},
|
|
1063
|
+
releasedAt: '2025-09-23',
|
|
1064
|
+
settings: {
|
|
1065
|
+
searchImpl: 'params',
|
|
1066
|
+
},
|
|
1067
|
+
type: 'chat',
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
abilities: {
|
|
1071
|
+
functionCall: true,
|
|
1072
|
+
reasoning: true,
|
|
1073
|
+
search: true,
|
|
1074
|
+
},
|
|
1075
|
+
config: {
|
|
1076
|
+
deploymentName: 'qwen3-max-preview', // 其支持上下文缓存
|
|
1077
|
+
},
|
|
1078
|
+
contextWindowTokens: 262_144,
|
|
1079
|
+
description: '通义千问系列效果最好的模型,适合复杂、多步骤的任务。预览版已支持思考。',
|
|
1080
|
+
displayName: 'Qwen3 Max Preview',
|
|
1081
|
+
id: 'qwen3-max-preview',
|
|
1082
|
+
maxOutput: 65_536,
|
|
1083
|
+
organization: 'Qwen',
|
|
1019
1084
|
pricing: {
|
|
1020
1085
|
currency: 'CNY',
|
|
1021
1086
|
units: [
|
|
@@ -1060,8 +1125,9 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1060
1125
|
},
|
|
1061
1126
|
],
|
|
1062
1127
|
},
|
|
1063
|
-
releasedAt: '2025-
|
|
1128
|
+
releasedAt: '2025-10-30',
|
|
1064
1129
|
settings: {
|
|
1130
|
+
extendParams: ['enableReasoning', 'reasoningBudgetToken'],
|
|
1065
1131
|
searchImpl: 'params',
|
|
1066
1132
|
},
|
|
1067
1133
|
type: 'chat',
|
|
@@ -1260,8 +1326,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1260
1326
|
},
|
|
1261
1327
|
{
|
|
1262
1328
|
abilities: {
|
|
1263
|
-
vision: true,
|
|
1264
1329
|
reasoning: true,
|
|
1330
|
+
vision: true,
|
|
1265
1331
|
},
|
|
1266
1332
|
contextWindowTokens: 131_072,
|
|
1267
1333
|
description:
|
|
@@ -1287,7 +1353,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1287
1353
|
vision: true,
|
|
1288
1354
|
},
|
|
1289
1355
|
contextWindowTokens: 131_072,
|
|
1290
|
-
description:
|
|
1356
|
+
description:
|
|
1357
|
+
'Qwen3 VL 30B 非思考模式(Instruct),面向普通指令跟随场景,保持较高的多模态理解与生成能力。',
|
|
1291
1358
|
displayName: 'Qwen3 VL 30B A3B Instruct',
|
|
1292
1359
|
id: 'qwen3-vl-30b-a3b-instruct',
|
|
1293
1360
|
maxOutput: 32_768,
|
|
@@ -1303,8 +1370,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1303
1370
|
},
|
|
1304
1371
|
{
|
|
1305
1372
|
abilities: {
|
|
1306
|
-
vision: true,
|
|
1307
1373
|
reasoning: true,
|
|
1374
|
+
vision: true,
|
|
1308
1375
|
},
|
|
1309
1376
|
contextWindowTokens: 131_072,
|
|
1310
1377
|
description: 'Qwen3 VL 8B 思考模式,面向轻量级多模态推理与交互场景,保留长上下文理解能力。',
|
|
@@ -1342,11 +1409,12 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1342
1409
|
},
|
|
1343
1410
|
{
|
|
1344
1411
|
abilities: {
|
|
1345
|
-
vision: true,
|
|
1346
1412
|
reasoning: true,
|
|
1413
|
+
vision: true,
|
|
1347
1414
|
},
|
|
1348
1415
|
contextWindowTokens: 131_072,
|
|
1349
|
-
description:
|
|
1416
|
+
description:
|
|
1417
|
+
'Qwen3 VL 235B A22B 思考模式(开源版),针对高难度强推理与长视频理解场景,提供顶尖的视觉+文本推理能力。',
|
|
1350
1418
|
displayName: 'Qwen3 VL 235B A22B Thinking',
|
|
1351
1419
|
id: 'qwen3-vl-235b-a22b-thinking',
|
|
1352
1420
|
maxOutput: 32_768,
|
|
@@ -1368,7 +1436,8 @@ const qwenChatModels: AIChatModelCard[] = [
|
|
|
1368
1436
|
vision: true,
|
|
1369
1437
|
},
|
|
1370
1438
|
contextWindowTokens: 131_072,
|
|
1371
|
-
description:
|
|
1439
|
+
description:
|
|
1440
|
+
'Qwen3 VL 235B A22B 非思考模式(Instruct),适用于非思考指令场景,保持强大的视觉理解能力。',
|
|
1372
1441
|
displayName: 'Qwen3 VL 235B A22B Instruct',
|
|
1373
1442
|
id: 'qwen3-vl-235b-a22b-instruct',
|
|
1374
1443
|
maxOutput: 32_768,
|
|
@@ -32,6 +32,7 @@ export interface LobeAgentChatConfig {
|
|
|
32
32
|
reasoningBudgetToken?: number;
|
|
33
33
|
reasoningEffort?: 'low' | 'medium' | 'high';
|
|
34
34
|
gpt5ReasoningEffort?: 'minimal' | 'low' | 'medium' | 'high';
|
|
35
|
+
gpt5_1ReasoningEffort?: 'none' | 'low' | 'medium' | 'high';
|
|
35
36
|
/**
|
|
36
37
|
* 输出文本详细程度控制
|
|
37
38
|
*/
|
|
@@ -66,6 +67,7 @@ export interface LobeAgentChatConfig {
|
|
|
66
67
|
|
|
67
68
|
export const AgentChatConfigSchema = z.object({
|
|
68
69
|
autoCreateTopicThreshold: z.number().default(2),
|
|
70
|
+
disableContextCaching: z.boolean().optional(),
|
|
69
71
|
displayMode: z.enum(['chat', 'docs']).optional(),
|
|
70
72
|
enableAutoCreateTopic: z.boolean().optional(),
|
|
71
73
|
enableCompressHistory: z.boolean().optional(),
|
|
@@ -74,8 +76,11 @@ export const AgentChatConfigSchema = z.object({
|
|
|
74
76
|
enableReasoning: z.boolean().optional(),
|
|
75
77
|
enableReasoningEffort: z.boolean().optional(),
|
|
76
78
|
enableStreaming: z.boolean().optional(),
|
|
79
|
+
gpt5ReasoningEffort: z.enum(['minimal', 'low', 'medium', 'high']).optional(),
|
|
80
|
+
gpt5_1ReasoningEffort: z.enum(['none', 'low', 'medium', 'high']).optional(),
|
|
77
81
|
historyCount: z.number().optional(),
|
|
78
82
|
reasoningBudgetToken: z.number().optional(),
|
|
83
|
+
reasoningEffort: z.enum(['low', 'medium', 'high']).optional(),
|
|
79
84
|
searchFCModel: z
|
|
80
85
|
.object({
|
|
81
86
|
model: z.string(),
|
|
@@ -84,4 +89,8 @@ export const AgentChatConfigSchema = z.object({
|
|
|
84
89
|
.optional(),
|
|
85
90
|
searchMode: z.enum(['off', 'on', 'auto']).optional(),
|
|
86
91
|
textVerbosity: z.enum(['low', 'medium', 'high']).optional(),
|
|
92
|
+
thinking: z.enum(['disabled', 'auto', 'enabled']).optional(),
|
|
93
|
+
thinkingBudget: z.number().optional(),
|
|
94
|
+
urlContext: z.boolean().optional(),
|
|
95
|
+
useModelBuiltinSearch: z.boolean().optional(),
|
|
87
96
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useTheme } from 'antd-style';
|
|
1
2
|
import { Suspense, memo } from 'react';
|
|
2
3
|
import { Flexbox } from 'react-layout-kit';
|
|
3
4
|
|
|
@@ -18,30 +19,38 @@ interface WorkspaceLayoutProps {
|
|
|
18
19
|
mobile?: boolean;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
|
-
const DesktopWorkspace = memo(() =>
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
22
|
+
const DesktopWorkspace = memo(() => {
|
|
23
|
+
const theme = useTheme();
|
|
24
|
+
|
|
25
|
+
return (
|
|
26
|
+
<>
|
|
27
|
+
<ChatHeaderDesktop />
|
|
28
|
+
<Flexbox
|
|
29
|
+
height={'100%'}
|
|
30
|
+
horizontal
|
|
31
|
+
style={{ overflow: 'hidden', position: 'relative' }}
|
|
32
|
+
width={'100%'}
|
|
33
|
+
>
|
|
34
|
+
<Flexbox
|
|
35
|
+
height={'100%'}
|
|
36
|
+
style={{ background: theme.colorBgContainer, overflow: 'hidden', position: 'relative' }}
|
|
37
|
+
width={'100%'}
|
|
38
|
+
>
|
|
39
|
+
<ConversationArea mobile={false} />
|
|
40
|
+
</Flexbox>
|
|
41
|
+
<Portal>
|
|
42
|
+
<Suspense fallback={<BrandTextLoading />}>
|
|
43
|
+
<PortalPanel mobile={false} />
|
|
44
|
+
</Suspense>
|
|
45
|
+
</Portal>
|
|
46
|
+
<TopicPanel>
|
|
47
|
+
<TopicSidebar mobile={false} />
|
|
48
|
+
</TopicPanel>
|
|
32
49
|
</Flexbox>
|
|
33
|
-
<
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
</Portal>
|
|
38
|
-
<TopicPanel>
|
|
39
|
-
<TopicSidebar mobile={false} />
|
|
40
|
-
</TopicPanel>
|
|
41
|
-
</Flexbox>
|
|
42
|
-
<MainInterfaceTracker />
|
|
43
|
-
</>
|
|
44
|
-
));
|
|
50
|
+
<MainInterfaceTracker />
|
|
51
|
+
</>
|
|
52
|
+
);
|
|
53
|
+
});
|
|
45
54
|
|
|
46
55
|
DesktopWorkspace.displayName = 'DesktopWorkspace';
|
|
47
56
|
|
|
@@ -12,6 +12,7 @@ import { aiModelSelectors, useAiInfraStore } from '@/store/aiInfra';
|
|
|
12
12
|
|
|
13
13
|
import ContextCachingSwitch from './ContextCachingSwitch';
|
|
14
14
|
import GPT5ReasoningEffortSlider from './GPT5ReasoningEffortSlider';
|
|
15
|
+
import GPT51ReasoningEffortSlider from './GPT51ReasoningEffortSlider';
|
|
15
16
|
import ReasoningEffortSlider from './ReasoningEffortSlider';
|
|
16
17
|
import ReasoningTokenSlider from './ReasoningTokenSlider';
|
|
17
18
|
import TextVerbositySlider from './TextVerbositySlider';
|
|
@@ -119,6 +120,17 @@ const ControlsForm = memo(() => {
|
|
|
119
120
|
paddingBottom: 0,
|
|
120
121
|
},
|
|
121
122
|
},
|
|
123
|
+
{
|
|
124
|
+
children: <GPT51ReasoningEffortSlider />,
|
|
125
|
+
desc: 'reasoning_effort',
|
|
126
|
+
label: t('extendParams.reasoningEffort.title'),
|
|
127
|
+
layout: 'horizontal',
|
|
128
|
+
minWidth: undefined,
|
|
129
|
+
name: 'gpt5_1ReasoningEffort',
|
|
130
|
+
style: {
|
|
131
|
+
paddingBottom: 0,
|
|
132
|
+
},
|
|
133
|
+
},
|
|
122
134
|
{
|
|
123
135
|
children: <TextVerbositySlider />,
|
|
124
136
|
desc: 'text_verbosity',
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { Slider } from 'antd';
|
|
2
|
+
import { memo, useCallback } from 'react';
|
|
3
|
+
import { Flexbox } from 'react-layout-kit';
|
|
4
|
+
|
|
5
|
+
import { useAgentStore } from '@/store/agent';
|
|
6
|
+
import { agentChatConfigSelectors } from '@/store/agent/selectors';
|
|
7
|
+
|
|
8
|
+
const GPT51ReasoningEffortSlider = memo(() => {
|
|
9
|
+
const [config, updateAgentChatConfig] = useAgentStore((s) => [
|
|
10
|
+
agentChatConfigSelectors.currentChatConfig(s),
|
|
11
|
+
s.updateAgentChatConfig,
|
|
12
|
+
]);
|
|
13
|
+
|
|
14
|
+
const gpt5_1ReasoningEffort = config.gpt5_1ReasoningEffort || 'none'; // Default to 'none' if not set
|
|
15
|
+
|
|
16
|
+
const marks = {
|
|
17
|
+
0: 'none',
|
|
18
|
+
1: 'low',
|
|
19
|
+
2: 'medium',
|
|
20
|
+
3: 'high',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const effortValues = ['none', 'low', 'medium', 'high'];
|
|
24
|
+
const indexValue = effortValues.indexOf(gpt5_1ReasoningEffort);
|
|
25
|
+
const currentValue = indexValue === -1 ? 0 : indexValue;
|
|
26
|
+
|
|
27
|
+
const updateGPT51ReasoningEffort = useCallback(
|
|
28
|
+
(value: number) => {
|
|
29
|
+
const effort = effortValues[value] as 'none' | 'low' | 'medium' | 'high';
|
|
30
|
+
updateAgentChatConfig({ gpt5_1ReasoningEffort: effort });
|
|
31
|
+
},
|
|
32
|
+
[updateAgentChatConfig],
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<Flexbox
|
|
37
|
+
align={'center'}
|
|
38
|
+
gap={12}
|
|
39
|
+
horizontal
|
|
40
|
+
paddingInline={'0 20px'}
|
|
41
|
+
style={{ minWidth: 200, width: '100%' }}
|
|
42
|
+
>
|
|
43
|
+
<Flexbox flex={1}>
|
|
44
|
+
<Slider
|
|
45
|
+
marks={marks}
|
|
46
|
+
max={3}
|
|
47
|
+
min={0}
|
|
48
|
+
onChange={updateGPT51ReasoningEffort}
|
|
49
|
+
step={1}
|
|
50
|
+
tooltip={{ open: false }}
|
|
51
|
+
value={currentValue}
|
|
52
|
+
/>
|
|
53
|
+
</Flexbox>
|
|
54
|
+
</Flexbox>
|
|
55
|
+
);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
export default GPT51ReasoningEffortSlider;
|
|
@@ -13,6 +13,7 @@ import { useStyles } from '../style';
|
|
|
13
13
|
import { ChatItemProps } from '../type';
|
|
14
14
|
|
|
15
15
|
export interface MessageContentProps {
|
|
16
|
+
className?: string;
|
|
16
17
|
disabled?: ChatItemProps['disabled'];
|
|
17
18
|
editing?: ChatItemProps['editing'];
|
|
18
19
|
id: string;
|
|
@@ -39,6 +40,7 @@ const MessageContent = memo<MessageContentProps>(
|
|
|
39
40
|
onDoubleClick,
|
|
40
41
|
markdownProps,
|
|
41
42
|
disabled,
|
|
43
|
+
className,
|
|
42
44
|
}) => {
|
|
43
45
|
const { t } = useTranslation('common');
|
|
44
46
|
const { cx, styles } = useStyles({ disabled, editing, placement, primary, variant });
|
|
@@ -81,7 +83,7 @@ const MessageContent = memo<MessageContentProps>(
|
|
|
81
83
|
|
|
82
84
|
return (
|
|
83
85
|
<Flexbox
|
|
84
|
-
className={cx(styles.message, editing && styles.editingContainer)}
|
|
86
|
+
className={cx(styles.message, editing && styles.editingContainer, className)}
|
|
85
87
|
onDoubleClick={onDoubleClick}
|
|
86
88
|
>
|
|
87
89
|
{messageContent}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
import { LOADING_FLAT } from '@lobechat/const';
|
|
4
4
|
import { UIChatMessage } from '@lobechat/types';
|
|
5
5
|
import { Tag } from '@lobehub/ui';
|
|
6
|
-
import { useResponsive } from 'antd-style';
|
|
6
|
+
import { css, cx, useResponsive } from 'antd-style';
|
|
7
7
|
import isEqual from 'fast-deep-equal';
|
|
8
8
|
import { ReactNode, memo, useCallback, useMemo } from 'react';
|
|
9
9
|
import { useTranslation } from 'react-i18next';
|
|
@@ -39,6 +39,11 @@ import { AssistantMessageContent } from './MessageContent';
|
|
|
39
39
|
const rehypePlugins = markdownElements.map((element) => element.rehypePlugin).filter(Boolean);
|
|
40
40
|
const remarkPlugins = markdownElements.map((element) => element.remarkPlugin).filter(Boolean);
|
|
41
41
|
|
|
42
|
+
const messageContainer = cx(css`
|
|
43
|
+
border: none;
|
|
44
|
+
background: none;
|
|
45
|
+
`);
|
|
46
|
+
|
|
42
47
|
const isHtmlCode = (content: string, language: string) => {
|
|
43
48
|
return (
|
|
44
49
|
language === 'html' ||
|
|
@@ -248,6 +253,7 @@ const AssistantMessage = memo<AssistantMessageProps>(({ id, index, disableEditin
|
|
|
248
253
|
<ErrorContent error={errorContent} message={errorMessage} placement={placement} />
|
|
249
254
|
) : (
|
|
250
255
|
<MessageContent
|
|
256
|
+
className={messageContainer}
|
|
251
257
|
editing={editing}
|
|
252
258
|
id={id}
|
|
253
259
|
markdownProps={markdownProps}
|
package/src/features/Conversation/Messages/Group/Tool/Render/Intervention/ApprovalActions.tsx
CHANGED
|
@@ -28,10 +28,12 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
28
28
|
const [approveLoading, setApproveLoading] = useState(false);
|
|
29
29
|
|
|
30
30
|
const { assistantGroupId } = useGroupMessage();
|
|
31
|
-
const [approveToolIntervention, rejectToolIntervention] =
|
|
32
|
-
s
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
const [approveToolIntervention, rejectToolIntervention, rejectAndContinueToolIntervention] =
|
|
32
|
+
useChatStore((s) => [
|
|
33
|
+
s.approveToolCalling,
|
|
34
|
+
s.rejectToolCalling,
|
|
35
|
+
s.rejectAndContinueToolCalling,
|
|
36
|
+
]);
|
|
35
37
|
const addToolToAllowList = useUserStore((s) => s.addToolToAllowList);
|
|
36
38
|
|
|
37
39
|
const handleApprove = async (remember?: boolean) => {
|
|
@@ -58,6 +60,14 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
58
60
|
setRejectReason('');
|
|
59
61
|
};
|
|
60
62
|
|
|
63
|
+
const handleRejectAndContinue = async (reason?: string) => {
|
|
64
|
+
setRejectLoading(true);
|
|
65
|
+
await rejectAndContinueToolIntervention(messageId, reason);
|
|
66
|
+
setRejectLoading(false);
|
|
67
|
+
setRejectPopoverOpen(false);
|
|
68
|
+
setRejectReason('');
|
|
69
|
+
};
|
|
70
|
+
|
|
61
71
|
return (
|
|
62
72
|
<Flexbox gap={8} horizontal>
|
|
63
73
|
<Popover
|
|
@@ -67,14 +77,25 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
67
77
|
<Flexbox align={'center'} horizontal justify={'space-between'}>
|
|
68
78
|
<div>{t('tool.intervention.rejectTitle')}</div>
|
|
69
79
|
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
80
|
+
<Space>
|
|
81
|
+
<Button
|
|
82
|
+
color={'default'}
|
|
83
|
+
loading={rejectLoading}
|
|
84
|
+
onClick={() => handleReject(rejectReason)}
|
|
85
|
+
size="small"
|
|
86
|
+
variant={'filled'}
|
|
87
|
+
>
|
|
88
|
+
{t('tool.intervention.rejectOnly')}
|
|
89
|
+
</Button>
|
|
90
|
+
<Button
|
|
91
|
+
loading={rejectLoading}
|
|
92
|
+
onClick={() => handleRejectAndContinue(rejectReason)}
|
|
93
|
+
size="small"
|
|
94
|
+
type="primary"
|
|
95
|
+
>
|
|
96
|
+
{t('tool.intervention.rejectAndContinue')}
|
|
97
|
+
</Button>
|
|
98
|
+
</Space>
|
|
78
99
|
</Flexbox>
|
|
79
100
|
<Input.TextArea
|
|
80
101
|
autoFocus
|
|
@@ -95,7 +116,7 @@ const ApprovalActions = memo<ApprovalActionsProps>(
|
|
|
95
116
|
placement="bottomRight"
|
|
96
117
|
trigger="click"
|
|
97
118
|
>
|
|
98
|
-
<Button size="small"
|
|
119
|
+
<Button color={'default'} size="small" variant={'filled'}>
|
|
99
120
|
{t('tool.intervention.reject')}
|
|
100
121
|
</Button>
|
|
101
122
|
</Popover>
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { UIChatMessage } from '@lobechat/types';
|
|
2
2
|
import { Tag } from '@lobehub/ui';
|
|
3
|
-
import { useResponsive } from 'antd-style';
|
|
3
|
+
import { createStyles, useResponsive } from 'antd-style';
|
|
4
4
|
import isEqual from 'fast-deep-equal';
|
|
5
5
|
import { ReactNode, memo, useCallback, useMemo } from 'react';
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
|
@@ -45,6 +45,13 @@ const remarkPlugins = markdownElements
|
|
|
45
45
|
.map((element) => element.remarkPlugin)
|
|
46
46
|
.filter(Boolean);
|
|
47
47
|
|
|
48
|
+
const useUserStyles = createStyles(({ css, token }) => ({
|
|
49
|
+
messageContainer: css`
|
|
50
|
+
border: none;
|
|
51
|
+
background: ${token.colorFillTertiary};
|
|
52
|
+
`,
|
|
53
|
+
}));
|
|
54
|
+
|
|
48
55
|
const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
|
|
49
56
|
const item = useChatStore(
|
|
50
57
|
displayMessageSelectors.getDisplayMessageById(id),
|
|
@@ -56,6 +63,8 @@ const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
|
|
|
56
63
|
const { t } = useTranslation('chat');
|
|
57
64
|
const { mobile } = useResponsive();
|
|
58
65
|
const avatar = useUserAvatar();
|
|
66
|
+
const { styles: userStyles } = useUserStyles();
|
|
67
|
+
|
|
59
68
|
const title = useUserStore(userProfileSelectors.displayUserName);
|
|
60
69
|
|
|
61
70
|
const displayMode = useAgentStore(agentChatConfigSelectors.displayMode);
|
|
@@ -165,6 +174,7 @@ const UserMessage = memo<UserMessageProps>(({ id, disableEditing, index }) => {
|
|
|
165
174
|
>
|
|
166
175
|
<Flexbox flex={1} style={{ maxWidth: '100%', minWidth: 0 }}>
|
|
167
176
|
<MessageContent
|
|
177
|
+
className={userStyles.messageContainer}
|
|
168
178
|
editing={editing}
|
|
169
179
|
id={id}
|
|
170
180
|
markdownProps={markdownProps}
|
|
@@ -5,8 +5,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
|
|
|
5
5
|
{
|
|
6
6
|
"description": "Echoes back a message with 'Hello' prefix",
|
|
7
7
|
"inputSchema": {
|
|
8
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
9
|
-
"additionalProperties": false,
|
|
10
8
|
"properties": {
|
|
11
9
|
"message": {
|
|
12
10
|
"description": "The message to echo",
|
|
@@ -23,8 +21,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
|
|
|
23
21
|
{
|
|
24
22
|
"description": "Lists all available tools and methods",
|
|
25
23
|
"inputSchema": {
|
|
26
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
27
|
-
"additionalProperties": false,
|
|
28
24
|
"properties": {},
|
|
29
25
|
"type": "object",
|
|
30
26
|
},
|
|
@@ -33,8 +29,6 @@ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
|
|
|
33
29
|
{
|
|
34
30
|
"description": "Adds two numbers",
|
|
35
31
|
"inputSchema": {
|
|
36
|
-
"$schema": "http://json-schema.org/draft-07/schema#",
|
|
37
|
-
"additionalProperties": false,
|
|
38
32
|
"properties": {
|
|
39
33
|
"a": {
|
|
40
34
|
"description": "The first number",
|
|
@@ -414,6 +414,8 @@ export default {
|
|
|
414
414
|
manualDesc: '每次调用都需要手动批准',
|
|
415
415
|
},
|
|
416
416
|
reject: '拒绝',
|
|
417
|
+
rejectAndContinue: '拒绝后重试执行',
|
|
418
|
+
rejectOnly: '拒绝',
|
|
417
419
|
rejectReasonPlaceholder: '输入拒绝原因将帮助 Agent 理解并优化后续行动',
|
|
418
420
|
rejectTitle: '拒绝本次工具调用',
|
|
419
421
|
rejectedWithReason: '本次工具调用被主动拒绝:{{reason}}',
|