@lobehub/chat 1.97.16 → 1.98.0

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/apps/desktop/package.json +8 -5
  3. package/apps/desktop/src/main/const/store.ts +12 -0
  4. package/apps/desktop/src/main/controllers/NetworkProxyCtr.ts +172 -0
  5. package/apps/desktop/src/main/controllers/__tests__/NetworkProxyCtr.test.ts +401 -0
  6. package/apps/desktop/src/main/core/Browser.ts +2 -0
  7. package/apps/desktop/src/main/modules/networkProxy/dispatcher.ts +116 -0
  8. package/apps/desktop/src/main/modules/networkProxy/index.ts +6 -0
  9. package/apps/desktop/src/main/modules/networkProxy/tester.ts +163 -0
  10. package/apps/desktop/src/main/modules/networkProxy/urlBuilder.ts +25 -0
  11. package/apps/desktop/src/main/modules/networkProxy/validator.ts +80 -0
  12. package/apps/desktop/src/main/types/store.ts +2 -1
  13. package/apps/desktop/src/main/utils/logger.ts +2 -1
  14. package/changelog/v1.json +18 -0
  15. package/locales/ar/electron.json +39 -0
  16. package/locales/ar/setting.json +1 -0
  17. package/locales/bg-BG/electron.json +39 -0
  18. package/locales/bg-BG/setting.json +1 -0
  19. package/locales/de-DE/electron.json +39 -0
  20. package/locales/de-DE/setting.json +1 -0
  21. package/locales/en-US/electron.json +39 -0
  22. package/locales/en-US/setting.json +1 -0
  23. package/locales/es-ES/electron.json +39 -0
  24. package/locales/es-ES/setting.json +1 -0
  25. package/locales/fa-IR/electron.json +39 -0
  26. package/locales/fa-IR/setting.json +1 -0
  27. package/locales/fr-FR/electron.json +39 -0
  28. package/locales/fr-FR/setting.json +1 -0
  29. package/locales/it-IT/electron.json +39 -0
  30. package/locales/it-IT/setting.json +1 -0
  31. package/locales/ja-JP/electron.json +39 -0
  32. package/locales/ja-JP/setting.json +1 -0
  33. package/locales/ko-KR/electron.json +39 -0
  34. package/locales/ko-KR/setting.json +1 -0
  35. package/locales/nl-NL/electron.json +39 -0
  36. package/locales/nl-NL/setting.json +1 -0
  37. package/locales/pl-PL/electron.json +39 -0
  38. package/locales/pl-PL/setting.json +1 -0
  39. package/locales/pt-BR/electron.json +39 -0
  40. package/locales/pt-BR/setting.json +1 -0
  41. package/locales/ru-RU/electron.json +39 -0
  42. package/locales/ru-RU/setting.json +1 -0
  43. package/locales/tr-TR/electron.json +39 -0
  44. package/locales/tr-TR/setting.json +1 -0
  45. package/locales/vi-VN/electron.json +39 -0
  46. package/locales/vi-VN/setting.json +1 -0
  47. package/locales/zh-CN/electron.json +39 -0
  48. package/locales/zh-CN/setting.json +1 -0
  49. package/locales/zh-TW/electron.json +39 -0
  50. package/locales/zh-TW/setting.json +1 -0
  51. package/package.json +3 -3
  52. package/packages/electron-client-ipc/src/events/index.ts +3 -1
  53. package/packages/electron-client-ipc/src/events/settings.ts +12 -0
  54. package/packages/electron-client-ipc/src/types/index.ts +1 -0
  55. package/packages/electron-client-ipc/src/types/proxy.ts +12 -0
  56. package/src/app/[variants]/(main)/settings/hooks/useCategory.tsx +11 -1
  57. package/src/app/[variants]/(main)/settings/proxy/features/ProxyForm.tsx +369 -0
  58. package/src/app/[variants]/(main)/settings/proxy/index.tsx +22 -0
  59. package/src/app/[variants]/(main)/settings/proxy/page.tsx +28 -0
  60. package/src/config/aiModels/google.ts +15 -26
  61. package/src/config/aiModels/groq.ts +0 -16
  62. package/src/config/aiModels/hunyuan.ts +79 -1
  63. package/src/config/aiModels/novita.ts +50 -56
  64. package/src/config/aiModels/qwen.ts +10 -32
  65. package/src/config/aiModels/siliconcloud.ts +111 -86
  66. package/src/config/aiModels/zhipu.ts +74 -12
  67. package/src/config/modelProviders/zhipu.ts +1 -2
  68. package/src/libs/model-runtime/hunyuan/index.ts +9 -1
  69. package/src/locales/default/electron.ts +39 -0
  70. package/src/locales/default/setting.ts +1 -0
  71. package/src/services/electron/settings.ts +33 -0
  72. package/src/store/electron/actions/settings.ts +55 -0
  73. package/src/store/electron/initialState.ts +12 -1
  74. package/src/store/electron/selectors/__tests__/desktopState.test.ts +3 -1
  75. package/src/store/electron/store.ts +4 -1
  76. package/src/store/global/initialState.ts +1 -0
  77. package/apps/desktop/scripts/pglite-server.ts +0 -14
@@ -1,6 +1,47 @@
1
1
  import { AIChatModelCard } from '@/types/aiModel';
2
2
 
3
3
  const zhipuChatModels: AIChatModelCard[] = [
4
+ {
5
+ abilities: {
6
+ reasoning: true,
7
+ search: true,
8
+ vision: true,
9
+ },
10
+ contextWindowTokens: 64_000,
11
+ description: 'GLM-4.1V-Thinking 系列模型是目前已知10B级别的VLM模型中性能最强的视觉模型,融合了同级别SOTA的各项视觉语言任务,包括视频理解、图片问答、学科解题、OCR文字识别、文档和图表解读、GUI Agent、前端网页Coding、Grounding等,多项任务能力甚至超过8倍参数量的Qwen2.5-VL-72B。通过领先的强化学习技术,模型掌握了通过思维链推理的方式提升回答的准确性和丰富度,从最终效果和可解释性等维度都显著超过传统的非thinking模型。',
12
+ displayName: 'GLM-4.1V-Thinking-FlashX',
13
+ id: 'glm-4.1v-thinking-flashx',
14
+ pricing: {
15
+ currency: 'CNY',
16
+ input: 2,
17
+ output: 2,
18
+ },
19
+ settings: {
20
+ searchImpl: 'params',
21
+ },
22
+ type: 'chat',
23
+ },
24
+ {
25
+ abilities: {
26
+ reasoning: true,
27
+ search: true,
28
+ vision: true,
29
+ },
30
+ contextWindowTokens: 64_000,
31
+ description: 'GLM-4.1V-Thinking 系列模型是目前已知10B级别的VLM模型中性能最强的视觉模型,融合了同级别SOTA的各项视觉语言任务,包括视频理解、图片问答、学科解题、OCR文字识别、文档和图表解读、GUI Agent、前端网页Coding、Grounding等,多项任务能力甚至超过8倍参数量的Qwen2.5-VL-72B。通过领先的强化学习技术,模型掌握了通过思维链推理的方式提升回答的准确性和丰富度,从最终效果和可解释性等维度都显著超过传统的非thinking模型。',
32
+ displayName: 'GLM-4.1V-Thinking-Flash',
33
+ enabled: true,
34
+ id: 'glm-4.1v-thinking-flash',
35
+ pricing: {
36
+ currency: 'CNY',
37
+ input: 0,
38
+ output: 0,
39
+ },
40
+ settings: {
41
+ searchImpl: 'params',
42
+ },
43
+ type: 'chat',
44
+ },
4
45
  {
5
46
  abilities: {
6
47
  reasoning: true,
@@ -21,11 +62,11 @@ const zhipuChatModels: AIChatModelCard[] = [
21
62
  reasoning: true,
22
63
  search: true,
23
64
  },
24
- contextWindowTokens: 32_000,
65
+ contextWindowTokens: 128_000,
25
66
  description: '推理模型: 具备强大推理能力,适用于需要深度推理的任务。',
26
67
  displayName: 'GLM-Z1-Air',
27
68
  id: 'glm-z1-air',
28
- maxOutput: 30_000,
69
+ maxOutput: 32_000,
29
70
  pricing: {
30
71
  currency: 'CNY',
31
72
  input: 0.5,
@@ -61,13 +102,34 @@ const zhipuChatModels: AIChatModelCard[] = [
61
102
  reasoning: true,
62
103
  search: true,
63
104
  },
64
- contextWindowTokens: 32_000,
105
+ contextWindowTokens: 128_000,
106
+ description:
107
+ '高速低价:Flash增强版本,超快推理速度,更快并发保障。',
108
+ displayName: 'GLM-Z1-FlashX',
109
+ id: 'glm-z1-flashx',
110
+ maxOutput: 32_000,
111
+ pricing: {
112
+ currency: 'CNY',
113
+ input: 0.1,
114
+ output: 0.1,
115
+ },
116
+ settings: {
117
+ searchImpl: 'params',
118
+ },
119
+ type: 'chat',
120
+ },
121
+ {
122
+ abilities: {
123
+ reasoning: true,
124
+ search: true,
125
+ },
126
+ contextWindowTokens: 128_000,
65
127
  description:
66
128
  'GLM-Z1 系列具备强大的复杂推理能力,在逻辑推理、数学、编程等领域表现优异。最大上下文长度为32K。',
67
129
  displayName: 'GLM-Z1-Flash',
68
130
  enabled: true,
69
131
  id: 'glm-z1-flash',
70
- maxOutput: 30_000,
132
+ maxOutput: 32_000,
71
133
  pricing: {
72
134
  currency: 'CNY',
73
135
  input: 0,
@@ -88,7 +150,7 @@ const zhipuChatModels: AIChatModelCard[] = [
88
150
  displayName: 'GLM-4-Flash-250414',
89
151
  enabled: true,
90
152
  id: 'glm-4-flash-250414',
91
- maxOutput: 4000,
153
+ maxOutput: 16_000,
92
154
  pricing: {
93
155
  currency: 'CNY',
94
156
  input: 0,
@@ -106,9 +168,9 @@ const zhipuChatModels: AIChatModelCard[] = [
106
168
  },
107
169
  contextWindowTokens: 128_000,
108
170
  description: 'GLM-4-FlashX 是Flash的增强版本,超快推理速度。',
109
- displayName: 'GLM-4-FlashX',
171
+ displayName: 'GLM-4-FlashX-250414',
110
172
  id: 'glm-4-flashx',
111
- maxOutput: 4000,
173
+ maxOutput: 16_000,
112
174
  pricing: {
113
175
  currency: 'CNY',
114
176
  input: 0.1,
@@ -144,11 +206,11 @@ const zhipuChatModels: AIChatModelCard[] = [
144
206
  functionCall: true,
145
207
  search: true,
146
208
  },
147
- contextWindowTokens: 32_000,
209
+ contextWindowTokens: 128_000,
148
210
  description: 'GLM-4-Air 是性价比高的版本,性能接近GLM-4,提供快速度和实惠的价格。',
149
211
  displayName: 'GLM-4-Air-250414',
150
212
  id: 'glm-4-air-250414',
151
- maxOutput: 4000,
213
+ maxOutput: 16_000,
152
214
  pricing: {
153
215
  currency: 'CNY',
154
216
  input: 0.5,
@@ -211,8 +273,8 @@ const zhipuChatModels: AIChatModelCard[] = [
211
273
  maxOutput: 4000,
212
274
  pricing: {
213
275
  currency: 'CNY',
214
- input: 50,
215
- output: 50,
276
+ input: 5,
277
+ output: 5,
216
278
  },
217
279
  settings: {
218
280
  searchImpl: 'params',
@@ -279,7 +341,7 @@ const zhipuChatModels: AIChatModelCard[] = [
279
341
  abilities: {
280
342
  vision: true,
281
343
  },
282
- contextWindowTokens: 8192,
344
+ contextWindowTokens: 16_000,
283
345
  description: 'GLM-4V-Plus 具备对视频内容及多图片的理解能力,适合多模态任务。',
284
346
  displayName: 'GLM-4V-Plus-0111',
285
347
  id: 'glm-4v-plus-0111',
@@ -9,7 +9,6 @@ const ZhiPu: ModelProviderCard = {
9
9
  contextWindowTokens: 16_384,
10
10
  description: 'GLM-Zero-Preview具备强大的复杂推理能力,在逻辑推理、数学、编程等领域表现优异。',
11
11
  displayName: 'GLM-Zero-Preview',
12
- enabled: true,
13
12
  id: 'glm-zero-preview',
14
13
  pricing: {
15
14
  currency: 'CNY',
@@ -207,7 +206,7 @@ const ZhiPu: ModelProviderCard = {
207
206
  },
208
207
  },
209
208
  ],
210
- checkModel: 'glm-4-flash',
209
+ checkModel: 'glm-4-flash-250414',
211
210
  description:
212
211
  '智谱 AI 提供多模态与语言模型的开放平台,支持广泛的AI应用场景,包括文本处理、图像理解与编程辅助等。',
213
212
  id: 'zhipu',
@@ -12,11 +12,12 @@ export const LobeHunyuanAI = createOpenAICompatibleRuntime({
12
12
  chatCompletion: {
13
13
  handlePayload: (payload) => {
14
14
  // eslint-disable-next-line unused-imports/no-unused-vars, @typescript-eslint/no-unused-vars
15
- const { enabledSearch, frequency_penalty, presence_penalty, ...rest } = payload;
15
+ const { enabledSearch, frequency_penalty, model, presence_penalty, thinking, ...rest } = payload;
16
16
 
17
17
  return {
18
18
  ...rest,
19
19
  frequency_penalty: undefined,
20
+ model,
20
21
  presence_penalty: undefined,
21
22
  stream: true,
22
23
  ...(enabledSearch && {
@@ -28,6 +29,13 @@ export const LobeHunyuanAI = createOpenAICompatibleRuntime({
28
29
  enable_speed_search: process.env.HUNYUAN_ENABLE_SPEED_SEARCH === '1',
29
30
  search_info: true,
30
31
  }),
32
+ ...(model === 'hunyuan-a13b' && {
33
+ enable_thinking: thinking?.type === 'enabled'
34
+ ? true
35
+ : thinking?.type === 'disabled'
36
+ ? false
37
+ : undefined
38
+ }),
31
39
  } as any;
32
40
  },
33
41
  },
@@ -1,4 +1,43 @@
1
1
  const electron = {
2
+ proxy: {
3
+ auth: '需要认证',
4
+ authDesc: '如果代理服务器需要用户名和密码',
5
+ authSettings: '认证设置',
6
+ basicSettings: '代理设置',
7
+ basicSettingsDesc: '配置代理服务器的连接参数',
8
+ bypass: '不使用代理的地址',
9
+ connectionTest: '连接测试',
10
+ enable: '启用代理',
11
+ enableDesc: '开启后将通过代理服务器访问网络',
12
+ password: '密码',
13
+ password_placeholder: '请输入密码',
14
+ port: '端口',
15
+ resetButton: '重置',
16
+ saveButton: '保存',
17
+ saveFailed: '保存失败:{{error}}',
18
+ saveSuccess: '代理设置保存成功',
19
+ server: '服务器地址',
20
+ testButton: '测试连接',
21
+ testDescription: '使用当前代理配置测试连接,验证配置是否正常工作',
22
+ testFailed: '连接失败',
23
+ testSuccessWithTime: '测试连接成功,耗时 {{time}} ms',
24
+ testUrl: '测试地址',
25
+ testUrlPlaceholder: '请输入要测试的 URL',
26
+ testing: '正在测试连接...',
27
+ type: '代理类型',
28
+ unsavedChanges: '您有未保存的更改',
29
+ username: '用户名',
30
+ username_placeholder: '请输入用户名',
31
+ validation: {
32
+ passwordRequired: '启用认证时密码为必填项',
33
+ portInvalid: '端口必须是 1 到 65535 之间的数字',
34
+ portRequired: '启用代理时端口为必填项',
35
+ serverInvalid: '请输入有效的服务器地址(IP 或域名)',
36
+ serverRequired: '启用代理时服务器地址为必填项',
37
+ typeRequired: '启用代理时代理类型为必填项',
38
+ usernameRequired: '启用认证时用户名为必填项',
39
+ },
40
+ },
2
41
  remoteServer: {
3
42
  authError: '授权失败: {{error}}',
4
43
  authPending: '请在浏览器中完成授权',
@@ -524,6 +524,7 @@ export default {
524
524
  'hotkey': '快捷键',
525
525
  'llm': '语言模型',
526
526
  'provider': 'AI 服务商',
527
+ 'proxy': '网络代理',
527
528
  'storage': '数据存储',
528
529
  'sync': '云端同步',
529
530
  'system-agent': '系统助手',
@@ -0,0 +1,33 @@
1
+ import { NetworkProxySettings, dispatch } from '@lobechat/electron-client-ipc';
2
+
3
+ class DesktopSettingsService {
4
+ /**
5
+ * 获取远程服务器配置
6
+ */
7
+ getProxySettings = async () => {
8
+ return dispatch('getProxySettings');
9
+ };
10
+
11
+ /**
12
+ * 设置远程服务器配置
13
+ */
14
+ setSettings = async (data: Partial<NetworkProxySettings>) => {
15
+ return dispatch('setProxySettings', data);
16
+ };
17
+
18
+ /**
19
+ * 测试代理连接
20
+ */
21
+ testProxyConnection = async (url: string) => {
22
+ return dispatch('testProxyConnection', url);
23
+ };
24
+
25
+ /**
26
+ * 测试指定的代理配置
27
+ */
28
+ testProxyConfig = async (config: NetworkProxySettings, testUrl?: string) => {
29
+ return dispatch('testProxyConfig', { config, testUrl });
30
+ };
31
+ }
32
+
33
+ export const desktopSettingsService = new DesktopSettingsService();
@@ -0,0 +1,55 @@
1
+ import { NetworkProxySettings } from '@lobechat/electron-client-ipc';
2
+ import isEqual from 'fast-deep-equal';
3
+ import useSWR, { SWRResponse, mutate } from 'swr';
4
+ import type { StateCreator } from 'zustand/vanilla';
5
+
6
+ import { desktopSettingsService } from '@/services/electron/settings';
7
+
8
+ import type { ElectronStore } from '../store';
9
+
10
+ /**
11
+ * 设置操作
12
+ */
13
+ export interface ElectronSettingsAction {
14
+ refreshProxySettings: () => Promise<void>;
15
+ setProxySettings: (params: Partial<NetworkProxySettings>) => Promise<void>;
16
+ useGetProxySettings: () => SWRResponse;
17
+ }
18
+
19
+ const ELECTRON_PROXY_SETTINGS_KEY = 'electron:getProxySettings';
20
+
21
+ export const settingsSlice: StateCreator<
22
+ ElectronStore,
23
+ [['zustand/devtools', never]],
24
+ [],
25
+ ElectronSettingsAction
26
+ > = (set, get) => ({
27
+ refreshProxySettings: async () => {
28
+ await mutate(ELECTRON_PROXY_SETTINGS_KEY);
29
+ },
30
+
31
+ setProxySettings: async (values) => {
32
+ try {
33
+ // 更新设置
34
+ await desktopSettingsService.setSettings(values);
35
+
36
+ // 刷新状态
37
+ await get().refreshProxySettings();
38
+ } catch (error) {
39
+ console.error('代理设置更新失败:', error);
40
+ }
41
+ },
42
+
43
+ useGetProxySettings: () =>
44
+ useSWR<NetworkProxySettings>(
45
+ ELECTRON_PROXY_SETTINGS_KEY,
46
+ async () => desktopSettingsService.getProxySettings(),
47
+ {
48
+ onSuccess: (data) => {
49
+ if (!isEqual(data, get().proxySettings)) {
50
+ set({ proxySettings: data });
51
+ }
52
+ },
53
+ },
54
+ ),
55
+ });
@@ -1,7 +1,16 @@
1
- import { DataSyncConfig, ElectronAppState } from '@lobechat/electron-client-ipc';
1
+ import { DataSyncConfig, ElectronAppState, NetworkProxySettings } from '@lobechat/electron-client-ipc';
2
2
 
3
3
  export type RemoteServerError = 'CONFIG_ERROR' | 'AUTH_ERROR' | 'DISCONNECT_ERROR';
4
4
 
5
+ export const defaultProxySettings: NetworkProxySettings = {
6
+ enableProxy: false,
7
+ proxyBypass: 'localhost, 127.0.0.1, ::1',
8
+ proxyPort: '',
9
+ proxyRequireAuth: false,
10
+ proxyServer: '',
11
+ proxyType: 'http',
12
+ };
13
+
5
14
  export interface ElectronState {
6
15
  appState: ElectronAppState;
7
16
  dataSyncConfig: DataSyncConfig;
@@ -9,6 +18,7 @@ export interface ElectronState {
9
18
  isConnectingServer?: boolean;
10
19
  isInitRemoteServerConfig: boolean;
11
20
  isSyncActive?: boolean;
21
+ proxySettings: NetworkProxySettings;
12
22
  remoteServerSyncError?: { message?: string; type: RemoteServerError };
13
23
  }
14
24
 
@@ -19,4 +29,5 @@ export const initialState: ElectronState = {
19
29
  isConnectingServer: false,
20
30
  isInitRemoteServerConfig: false,
21
31
  isSyncActive: false,
32
+ proxySettings: defaultProxySettings,
22
33
  };
@@ -1,6 +1,6 @@
1
1
  import { describe, expect, it } from 'vitest';
2
2
 
3
- import { ElectronState } from '@/store/electron/initialState';
3
+ import { ElectronState, defaultProxySettings } from '@/store/electron/initialState';
4
4
 
5
5
  import { desktopStateSelectors } from '../desktopState';
6
6
 
@@ -25,6 +25,7 @@ describe('desktopStateSelectors', () => {
25
25
  storageMode: 'local',
26
26
  },
27
27
  isInitRemoteServerConfig: false,
28
+ proxySettings: defaultProxySettings,
28
29
  };
29
30
 
30
31
  expect(desktopStateSelectors.usePath(state)).toEqual({
@@ -47,6 +48,7 @@ describe('desktopStateSelectors', () => {
47
48
  storageMode: 'local',
48
49
  },
49
50
  isInitRemoteServerConfig: false,
51
+ proxySettings: defaultProxySettings,
50
52
  };
51
53
 
52
54
  expect(desktopStateSelectors.usePath(state)).toBeUndefined();
@@ -4,6 +4,7 @@ import { StateCreator } from 'zustand/vanilla';
4
4
 
5
5
  import { createDevtools } from '../middleware/createDevtools';
6
6
  import { type ElectronAppAction, createElectronAppSlice } from './actions/app';
7
+ import { type ElectronSettingsAction, settingsSlice } from './actions/settings';
7
8
  import { type ElectronRemoteServerAction, remoteSyncSlice } from './actions/sync';
8
9
  import { type ElectronState, initialState } from './initialState';
9
10
 
@@ -12,7 +13,8 @@ import { type ElectronState, initialState } from './initialState';
12
13
  export interface ElectronStore
13
14
  extends ElectronState,
14
15
  ElectronRemoteServerAction,
15
- ElectronAppAction {
16
+ ElectronAppAction,
17
+ ElectronSettingsAction {
16
18
  /* empty */
17
19
  }
18
20
 
@@ -22,6 +24,7 @@ const createStore: StateCreator<ElectronStore, [['zustand/devtools', never]]> =
22
24
  ...initialState,
23
25
  ...remoteSyncSlice(...parameters),
24
26
  ...createElectronAppSlice(...parameters),
27
+ ...settingsSlice(...parameters),
25
28
  });
26
29
 
27
30
  // =============== 实装 useStore ============ //
@@ -31,6 +31,7 @@ export enum SettingsTabs {
31
31
  Hotkey = 'hotkey',
32
32
  LLM = 'llm',
33
33
  Provider = 'provider',
34
+ Proxy = 'proxy',
34
35
  Storage = 'storage',
35
36
  Sync = 'sync',
36
37
  SystemAgent = 'system-agent',
@@ -1,14 +0,0 @@
1
- import { PGlite } from "@electric-sql/pglite";
2
- import { createServer } from "pglite-server";
3
-
4
- // 创建或连接到您现有的 PGlite 数据库
5
- const db = new PGlite("/Users/arvinxx/Library/Application Support/lobehub-desktop/lobehub-local-db");
6
- await db.waitReady;
7
-
8
- // 创建服务器并监听端口
9
- const PORT = 6543;
10
- const pgServer = createServer(db);
11
-
12
- pgServer.listen(PORT, () => {
13
- console.log(`PGlite 服务器已启动,监听端口 ${PORT}`);
14
- });