@lobehub/chat 1.109.0 → 1.110.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 (100) hide show
  1. package/.cursor/rules/i18n.mdc +1 -2
  2. package/CHANGELOG.md +59 -0
  3. package/README.md +1 -1
  4. package/README.zh-CN.md +1 -1
  5. package/apps/desktop/electron-builder.js +22 -0
  6. package/apps/desktop/src/main/controllers/McpInstallCtr.ts +153 -0
  7. package/apps/desktop/src/main/controllers/index.ts +19 -0
  8. package/apps/desktop/src/main/core/App.ts +46 -0
  9. package/apps/desktop/src/main/core/infrastructure/IoCContainer.ts +4 -0
  10. package/apps/desktop/src/main/core/infrastructure/ProtocolManager.ts +256 -0
  11. package/apps/desktop/src/main/types/protocol.ts +60 -0
  12. package/apps/desktop/src/main/utils/__tests__/protocol.test.ts +203 -0
  13. package/apps/desktop/src/main/utils/protocol.ts +210 -0
  14. package/changelog/v1.json +21 -0
  15. package/locales/ar/models.json +6 -0
  16. package/locales/ar/plugin.json +196 -136
  17. package/locales/ar/providers.json +3 -0
  18. package/locales/bg-BG/models.json +6 -0
  19. package/locales/bg-BG/plugin.json +204 -144
  20. package/locales/bg-BG/providers.json +3 -0
  21. package/locales/de-DE/models.json +6 -0
  22. package/locales/de-DE/plugin.json +176 -116
  23. package/locales/de-DE/providers.json +3 -0
  24. package/locales/en-US/models.json +6 -0
  25. package/locales/en-US/plugin.json +192 -132
  26. package/locales/en-US/providers.json +3 -0
  27. package/locales/es-ES/models.json +6 -0
  28. package/locales/es-ES/plugin.json +203 -143
  29. package/locales/es-ES/providers.json +3 -0
  30. package/locales/fa-IR/models.json +6 -0
  31. package/locales/fa-IR/plugin.json +155 -95
  32. package/locales/fa-IR/providers.json +3 -0
  33. package/locales/fr-FR/models.json +6 -0
  34. package/locales/fr-FR/plugin.json +161 -101
  35. package/locales/fr-FR/providers.json +3 -0
  36. package/locales/it-IT/models.json +6 -0
  37. package/locales/it-IT/plugin.json +193 -133
  38. package/locales/it-IT/providers.json +3 -0
  39. package/locales/ja-JP/models.json +6 -0
  40. package/locales/ja-JP/plugin.json +195 -135
  41. package/locales/ja-JP/providers.json +3 -0
  42. package/locales/ko-KR/models.json +6 -0
  43. package/locales/ko-KR/plugin.json +163 -103
  44. package/locales/ko-KR/providers.json +3 -0
  45. package/locales/nl-NL/models.json +6 -0
  46. package/locales/nl-NL/plugin.json +211 -151
  47. package/locales/nl-NL/providers.json +3 -0
  48. package/locales/pl-PL/models.json +6 -0
  49. package/locales/pl-PL/plugin.json +171 -111
  50. package/locales/pl-PL/providers.json +3 -0
  51. package/locales/pt-BR/models.json +6 -0
  52. package/locales/pt-BR/plugin.json +180 -120
  53. package/locales/pt-BR/providers.json +3 -0
  54. package/locales/ru-RU/models.json +6 -0
  55. package/locales/ru-RU/plugin.json +191 -131
  56. package/locales/ru-RU/providers.json +3 -0
  57. package/locales/tr-TR/models.json +6 -0
  58. package/locales/tr-TR/plugin.json +187 -127
  59. package/locales/tr-TR/providers.json +3 -0
  60. package/locales/vi-VN/models.json +6 -0
  61. package/locales/vi-VN/plugin.json +152 -92
  62. package/locales/vi-VN/providers.json +3 -0
  63. package/locales/zh-CN/models.json +6 -0
  64. package/locales/zh-CN/plugin.json +60 -0
  65. package/locales/zh-CN/providers.json +3 -0
  66. package/locales/zh-TW/models.json +6 -0
  67. package/locales/zh-TW/plugin.json +157 -97
  68. package/locales/zh-TW/providers.json +3 -0
  69. package/package.json +2 -1
  70. package/packages/electron-client-ipc/src/events/index.ts +5 -2
  71. package/packages/electron-client-ipc/src/events/protocol.ts +29 -0
  72. package/packages/electron-client-ipc/src/types/index.ts +1 -0
  73. package/packages/electron-client-ipc/src/types/mcpInstall.ts +19 -0
  74. package/packages/types/src/plugins/mcp.ts +38 -1
  75. package/packages/types/src/plugins/protocol.ts +166 -0
  76. package/src/app/[variants]/(main)/chat/_layout/Desktop/index.tsx +4 -1
  77. package/src/app/[variants]/(main)/discover/(detail)/mcp/[slug]/features/Sidebar/ActionButton/index.tsx +1 -2
  78. package/src/components/KeyValueEditor/index.tsx +4 -2
  79. package/src/config/aiModels/aihubmix.ts +465 -30
  80. package/src/config/aiModels/anthropic.ts +27 -1
  81. package/src/config/aiModels/groq.ts +40 -4
  82. package/src/config/aiModels/qwen.ts +24 -2
  83. package/src/features/MCP/MCPInstallProgress/index.tsx +1 -1
  84. package/src/features/PluginDevModal/MCPManifestForm/index.tsx +30 -36
  85. package/src/features/PluginStore/McpList/List/Item.tsx +1 -1
  86. package/src/features/ProtocolUrlHandler/InstallPlugin/ConfigDisplay.tsx +211 -0
  87. package/src/features/ProtocolUrlHandler/InstallPlugin/CustomPluginInstallModal.tsx +228 -0
  88. package/src/features/ProtocolUrlHandler/InstallPlugin/OfficialPluginInstallModal/Detail.tsx +44 -0
  89. package/src/features/ProtocolUrlHandler/InstallPlugin/OfficialPluginInstallModal/index.tsx +105 -0
  90. package/src/features/ProtocolUrlHandler/InstallPlugin/index.tsx +55 -0
  91. package/src/features/ProtocolUrlHandler/InstallPlugin/types.ts +45 -0
  92. package/src/features/ProtocolUrlHandler/index.tsx +30 -0
  93. package/src/libs/model-runtime/anthropic/index.ts +15 -2
  94. package/src/libs/model-runtime/utils/modelParse.ts +2 -2
  95. package/src/libs/model-runtime/utils/streams/ollama.test.ts +97 -51
  96. package/src/libs/model-runtime/utils/streams/ollama.ts +4 -0
  97. package/src/locales/default/plugin.ts +60 -0
  98. package/src/store/tool/slices/mcpStore/action.ts +127 -1
  99. package/src/store/tool/slices/mcpStore/initialState.ts +8 -13
  100. package/src/store/tool/slices/mcpStore/selectors.ts +13 -0
@@ -0,0 +1,60 @@
1
+ /**
2
+ * MCP Schema - stdio 配置类型
3
+ */
4
+ export interface McpStdioConfig {
5
+ args?: string[];
6
+ command: string;
7
+ env?: Record<string, string>;
8
+ type: 'stdio';
9
+ }
10
+
11
+ /**
12
+ * MCP Schema - http 配置类型
13
+ */
14
+ export interface McpHttpConfig {
15
+ headers?: Record<string, string>;
16
+ type: 'http';
17
+ url: string;
18
+ }
19
+
20
+ /**
21
+ * MCP Schema 配置类型
22
+ */
23
+ export type McpConfig = McpStdioConfig | McpHttpConfig;
24
+
25
+ /**
26
+ * MCP Schema 对象
27
+ * 符合 RFC 0001 定义
28
+ */
29
+ export interface McpSchema {
30
+ /** 插件作者 */
31
+ author: string;
32
+ /** 插件配置 */
33
+ config: McpConfig;
34
+ /** 插件描述 */
35
+ description: string;
36
+ /** 插件主页 */
37
+ homepage?: string;
38
+ /** 插件图标 */
39
+ icon?: string;
40
+ /** 插件唯一标识符,必须与URL中的id参数匹配 */
41
+ identifier: string;
42
+ /** 插件名称 */
43
+ name: string;
44
+ /** 插件版本 (semver) */
45
+ version: string;
46
+ }
47
+
48
+ /**
49
+ * 协议URL解析结果
50
+ */
51
+ export interface ProtocolUrlParsed {
52
+ /** 操作类型 (如: 'install') */
53
+ action: string;
54
+ /** 原始URL */
55
+ originalUrl: string;
56
+ /** 解析后的所有查询参数 */
57
+ params: Record<string, string>;
58
+ /** URL类型 (如: 'plugin') */
59
+ urlType: string;
60
+ }
@@ -0,0 +1,203 @@
1
+ import { describe, expect, it } from 'vitest';
2
+
3
+ import { McpSchema } from '../../types/protocol';
4
+ import { generateRFCProtocolUrl, parseProtocolUrl } from '../protocol';
5
+
6
+ describe('Protocol', () => {
7
+ describe('generateRFCProtocolUrl', () => {
8
+ it('should generate valid RFC protocol URL for stdio type', () => {
9
+ const schema: McpSchema = {
10
+ identifier: 'edgeone-mcp',
11
+ name: 'EdgeOne MCP',
12
+ author: 'Higress Team',
13
+ description: 'EdgeOne API integration for LobeChat',
14
+ version: '1.0.0',
15
+ homepage: 'https://github.com/higress/edgeone-mcp',
16
+ config: {
17
+ type: 'stdio',
18
+ command: 'npx',
19
+ args: ['-y', '@higress/edgeone-mcp'],
20
+ env: { NODE_ENV: 'production' },
21
+ },
22
+ };
23
+
24
+ const url = generateRFCProtocolUrl({
25
+ id: 'edgeone-mcp',
26
+ schema,
27
+ marketId: 'higress',
28
+ });
29
+
30
+ expect(url).toMatch(/^lobehub:\/\/plugin\/install\?/);
31
+ expect(url).toContain('id=edgeone-mcp');
32
+ expect(url).toContain('marketId=higress');
33
+
34
+ // Verify schema is URL encoded
35
+ const urlObj = new URL(url);
36
+ const schemaParam = urlObj.searchParams.get('schema');
37
+ expect(schemaParam).toBeTruthy();
38
+ // URLSearchParams.get() 自动解码,所以这里得到的是解码后的JSON
39
+ expect(schemaParam).toContain('"'); // 解码后的引号
40
+ });
41
+
42
+ it('should generate valid RFC protocol URL for http type', () => {
43
+ const schema: McpSchema = {
44
+ identifier: 'awesome-api',
45
+ name: 'Awesome API',
46
+ author: 'Smithery',
47
+ description: 'Awesome API integration',
48
+ version: '2.0.0',
49
+ config: {
50
+ type: 'http',
51
+ url: 'https://api.smithery.ai/v1/mcp',
52
+ headers: {
53
+ 'Authorization': 'Bearer token123',
54
+ 'X-Custom-Header': 'value',
55
+ },
56
+ },
57
+ };
58
+
59
+ const url = generateRFCProtocolUrl({
60
+ id: 'awesome-api',
61
+ schema,
62
+ marketId: 'smithery',
63
+ });
64
+
65
+ expect(url).toMatch(/^lobehub:\/\/plugin\/install\?/);
66
+ expect(url).toContain('id=awesome-api');
67
+ expect(url).toContain('marketId=smithery');
68
+ });
69
+
70
+ it('should throw error if schema identifier does not match id', () => {
71
+ const schema: McpSchema = {
72
+ identifier: 'wrong-id',
73
+ name: 'Test',
74
+ author: 'Test',
75
+ description: 'Test',
76
+ version: '1.0.0',
77
+ config: { type: 'stdio', command: 'test' },
78
+ };
79
+
80
+ expect(() => generateRFCProtocolUrl({ id: 'different-id', schema })).toThrowError(
81
+ 'Schema identifier must match the id parameter',
82
+ );
83
+ });
84
+ });
85
+
86
+ describe('parseProtocolUrl', () => {
87
+ it('should parse RFC protocol URL correctly', () => {
88
+ const schema: McpSchema = {
89
+ identifier: 'test-mcp',
90
+ name: 'Test MCP',
91
+ author: 'Test Author',
92
+ description: 'Test Description',
93
+ version: '1.0.0',
94
+ config: {
95
+ type: 'stdio',
96
+ command: 'test',
97
+ args: ['arg1', 'arg2'],
98
+ },
99
+ };
100
+
101
+ const url = generateRFCProtocolUrl({
102
+ id: 'test-mcp',
103
+ schema,
104
+ marketId: 'lobehub',
105
+ });
106
+
107
+ const parsed = parseProtocolUrl(url);
108
+
109
+ expect(parsed).toBeTruthy();
110
+ expect(parsed?.urlType).toBe('plugin');
111
+ expect(parsed?.action).toBe('install');
112
+ expect(parsed?.params.type).toBe('mcp');
113
+ expect(parsed?.params.id).toBe('test-mcp');
114
+ expect(parsed?.params.marketId).toBe('lobehub');
115
+ expect(parsed?.originalUrl).toBe(url);
116
+
117
+ // 验证 schema 可以被解析
118
+ const parsedSchema = JSON.parse(parsed?.params.schema || '{}');
119
+ expect(parsedSchema).toEqual(schema);
120
+ });
121
+
122
+ it('should return null for invalid protocol', () => {
123
+ const result = parseProtocolUrl('http://example.com');
124
+ expect(result).toBeNull();
125
+ });
126
+
127
+ it('should parse URLs with any action', () => {
128
+ const result = parseProtocolUrl('lobehub://plugin/configure?id=test');
129
+ expect(result).toBeTruthy();
130
+ expect(result?.urlType).toBe('plugin');
131
+ expect(result?.action).toBe('configure');
132
+ expect(result?.params.id).toBe('test');
133
+ });
134
+
135
+ it('should parse URLs with any query parameters', () => {
136
+ const result = parseProtocolUrl('lobehub://plugin/install?custom=value&another=param');
137
+ expect(result).toBeTruthy();
138
+ expect(result?.urlType).toBe('plugin');
139
+ expect(result?.action).toBe('install');
140
+ expect(result?.params.custom).toBe('value');
141
+ expect(result?.params.another).toBe('param');
142
+ });
143
+
144
+ it('should handle URLs without query parameters', () => {
145
+ const result = parseProtocolUrl('lobehub://plugin/install');
146
+ expect(result).toBeTruthy();
147
+ expect(result?.urlType).toBe('plugin');
148
+ expect(result?.action).toBe('install');
149
+ expect(Object.keys(result?.params || {})).toHaveLength(0);
150
+ });
151
+
152
+ it('should return null for URLs without action', () => {
153
+ const result = parseProtocolUrl('lobehub://plugin/');
154
+ expect(result).toBeNull();
155
+ });
156
+ });
157
+
158
+ describe('URL encoding/decoding', () => {
159
+ it('should handle special characters correctly', () => {
160
+ const schema: McpSchema = {
161
+ identifier: 'special-chars',
162
+ name: '特殊字符 ñ 🚀',
163
+ author: 'Test <test@example.com>',
164
+ description: 'Description with "quotes" and \'apostrophes\'',
165
+ version: '1.0.0',
166
+ config: {
167
+ type: 'stdio',
168
+ command: 'cmd',
169
+ args: ['arg with spaces', 'arg/with/slashes'],
170
+ },
171
+ };
172
+
173
+ const url = generateRFCProtocolUrl({ id: 'special-chars', schema });
174
+ const parsed = parseProtocolUrl(url);
175
+
176
+ expect(parsed).toBeTruthy();
177
+ expect(parsed?.params.id).toBe('special-chars');
178
+ expect(parsed?.params.type).toBe('mcp');
179
+
180
+ // 验证 schema 可以正确解析
181
+ const parsedSchema = JSON.parse(parsed?.params.schema || '{}');
182
+ expect(parsedSchema).toEqual(schema);
183
+ });
184
+
185
+ it('should handle different protocol schemes', () => {
186
+ const testCases = [
187
+ 'lobehub://plugin/install?test=value',
188
+ 'lobehub-dev://plugin/install?test=value',
189
+ 'lobehub-beta://plugin/install?test=value',
190
+ 'lobehub-nightly://plugin/install?test=value',
191
+ ];
192
+
193
+ testCases.forEach((url) => {
194
+ const parsed = parseProtocolUrl(url);
195
+ expect(parsed).toBeTruthy();
196
+ expect(parsed?.urlType).toBe('plugin');
197
+ expect(parsed?.action).toBe('install');
198
+ expect(parsed?.params.test).toBe('value');
199
+ expect(parsed?.originalUrl).toBe(url);
200
+ });
201
+ });
202
+ });
203
+ });
@@ -0,0 +1,210 @@
1
+ import { app } from 'electron';
2
+
3
+ import { McpSchema, ProtocolUrlParsed } from '../types/protocol';
4
+
5
+ export type AppChannel = 'stable' | 'beta' | 'nightly';
6
+
7
+ export const getProtocolScheme = (): string => {
8
+ // 在 Electron 环境中可以通过多种方式判断版本
9
+ const bundleId = app.name;
10
+ const appPath = app.getPath('exe');
11
+
12
+ // 通过 bundle identifier 判断
13
+ if (bundleId?.toLowerCase().includes('nightly')) return 'lobehub-nightly';
14
+ if (bundleId?.toLowerCase().includes('beta')) return 'lobehub-beta';
15
+ if (bundleId?.includes('dev')) return 'lobehub-dev';
16
+
17
+ // 通过可执行文件路径判断
18
+ if (appPath?.toLowerCase().includes('nightly')) return 'lobehub-nightly';
19
+ if (appPath?.toLowerCase().includes('beta')) return 'lobehub-beta';
20
+ if (appPath?.includes('dev')) return 'lobehub-dev';
21
+
22
+ return 'lobehub';
23
+ };
24
+
25
+ export const getVersionInfo = (): { channel: AppChannel; protocolScheme: string } => {
26
+ const protocolScheme = getProtocolScheme();
27
+
28
+ let appChannel: AppChannel = 'stable';
29
+ if (protocolScheme.includes('nightly')) {
30
+ appChannel = 'nightly';
31
+ } else if (protocolScheme.includes('beta')) {
32
+ appChannel = 'beta';
33
+ }
34
+
35
+ return {
36
+ channel: appChannel,
37
+ protocolScheme,
38
+ };
39
+ };
40
+
41
+ /**
42
+ * 验证 MCP Schema 对象结构
43
+ * @param schema 待验证的对象
44
+ * @returns 是否为有效的 MCP Schema
45
+ */
46
+ function validateMcpSchema(schema: any): schema is McpSchema {
47
+ if (!schema || typeof schema !== 'object') return false;
48
+
49
+ // 必填字段验证
50
+ if (typeof schema.identifier !== 'string' || !schema.identifier) return false;
51
+ if (typeof schema.name !== 'string' || !schema.name) return false;
52
+ if (typeof schema.author !== 'string' || !schema.author) return false;
53
+ if (typeof schema.description !== 'string' || !schema.description) return false;
54
+ if (typeof schema.version !== 'string' || !schema.version) return false;
55
+
56
+ // 可选字段验证
57
+ if (schema.homepage !== undefined && typeof schema.homepage !== 'string') return false;
58
+ if (schema.icon !== undefined && typeof schema.icon !== 'string') return false;
59
+
60
+ // config 字段验证
61
+ if (!schema.config || typeof schema.config !== 'object') return false;
62
+ const config = schema.config;
63
+
64
+ if (config.type === 'stdio') {
65
+ if (typeof config.command !== 'string' || !config.command) return false;
66
+ if (config.args !== undefined && !Array.isArray(config.args)) return false;
67
+ if (config.env !== undefined && typeof config.env !== 'object') return false;
68
+ } else if (config.type === 'http') {
69
+ if (typeof config.url !== 'string' || !config.url) return false;
70
+ try {
71
+ new URL(config.url); // 验证URL格式
72
+ } catch {
73
+ return false;
74
+ }
75
+ if (config.headers !== undefined && typeof config.headers !== 'object') return false;
76
+ } else {
77
+ return false; // 未知的 config type
78
+ }
79
+
80
+ return true;
81
+ }
82
+
83
+ /**
84
+ * 解析 lobehub:// 协议 URL (支持多版本协议)
85
+ *
86
+ * 支持的URL格式:
87
+ * - lobehub://plugin/install?id=figma&schema=xxx&marketId=lobehub
88
+ * - lobehub://plugin/configure?id=xxx&...
89
+ * - lobehub-bet://plugin/install?id=figma&schema=xxx&marketId=lobehub
90
+ * - lobehub-nightly://plugin/install?id=figma&schema=xxx&marketId=lobehub
91
+ * - lobehub-dev://plugin/install?id=figma&schema=xxx&marketId=lobehub
92
+ *
93
+ * @param url 协议 URL
94
+ * @returns 解析结果,包含基本结构和所有查询参数
95
+ */
96
+ export const parseProtocolUrl = (url: string): ProtocolUrlParsed | null => {
97
+ try {
98
+ const parsedUrl = new URL(url);
99
+
100
+ // 支持多种协议 scheme
101
+ const validProtocols = ['lobehub:', 'lobehub-dev:', 'lobehub-nightly:', 'lobehub-beta:'];
102
+ if (!validProtocols.includes(parsedUrl.protocol)) {
103
+ return null;
104
+ }
105
+
106
+ // 对于自定义协议,URL 解析后:
107
+ // lobehub://plugin/install -> hostname: "plugin", pathname: "/install"
108
+ const urlType = parsedUrl.hostname; // "plugin"
109
+ const pathParts = parsedUrl.pathname.split('/').filter(Boolean); // ["install"]
110
+
111
+ if (pathParts.length < 1) {
112
+ return null;
113
+ }
114
+
115
+ const action = pathParts[0]; // "install"
116
+
117
+ // 解析所有查询参数
118
+ const params: Record<string, string> = {};
119
+ const searchParams = new URLSearchParams(parsedUrl.search);
120
+
121
+ for (const [key, value] of searchParams.entries()) {
122
+ params[key] = value;
123
+ }
124
+
125
+ return {
126
+ action,
127
+ originalUrl: url,
128
+ params,
129
+ urlType,
130
+ };
131
+ } catch (error) {
132
+ console.error('Failed to parse protocol URL:', error);
133
+ return null;
134
+ }
135
+ };
136
+
137
+ /**
138
+ * 生成符合 RFC 0001 的协议 URL
139
+ *
140
+ * @param params 协议参数
141
+ * @returns 生成的协议URL
142
+ */
143
+ export function generateRFCProtocolUrl(params: {
144
+ /** 插件唯一标识符 */
145
+ id: string;
146
+ /** Marketplace ID */
147
+ marketId?: string;
148
+ /** MCP Schema 对象 */
149
+ schema: McpSchema;
150
+ /** 协议 scheme (默认: lobehub) */
151
+ scheme?: string;
152
+ }): string {
153
+ const { id, schema, marketId, scheme = 'lobehub' } = params;
154
+
155
+ // 验证 schema.identifier 与 id 匹配
156
+ if (schema.identifier !== id) {
157
+ throw new Error('Schema identifier must match the id parameter');
158
+ }
159
+
160
+ // 验证 schema 结构
161
+ if (!validateMcpSchema(schema)) {
162
+ throw new Error('Invalid MCP Schema structure');
163
+ }
164
+
165
+ // 构建基础 URL
166
+ const baseUrl = `${scheme}://plugin/install`;
167
+
168
+ // 构建查询参数
169
+ const searchParams = new URLSearchParams();
170
+
171
+ // 必需参数
172
+ searchParams.set('type', 'mcp');
173
+ searchParams.set('id', id);
174
+
175
+ // 编码 schema - 直接传 JSON 字符串,让 URLSearchParams 自动编码
176
+ const schemaJson = JSON.stringify(schema);
177
+ searchParams.set('schema', schemaJson);
178
+
179
+ // 可选参数
180
+ if (marketId) {
181
+ searchParams.set('marketId', marketId);
182
+ }
183
+
184
+ return `${baseUrl}?${searchParams.toString()}`;
185
+ }
186
+
187
+ /**
188
+ * 生成协议 URL 示例
189
+ *
190
+ * @example
191
+ * ```typescript
192
+ * const url = generateRFCProtocolUrl({
193
+ * id: 'edgeone-mcp',
194
+ * schema: {
195
+ * identifier: 'edgeone-mcp',
196
+ * name: 'EdgeOne MCP',
197
+ * author: 'Higress Team',
198
+ * description: 'EdgeOne API integration for LobeChat',
199
+ * version: '1.0.0',
200
+ * config: {
201
+ * type: 'stdio',
202
+ * command: 'npx',
203
+ * args: ['-y', '@higress/edgeone-mcp']
204
+ * }
205
+ * },
206
+ * marketId: 'higress'
207
+ * });
208
+ * // Result: lobehub://plugin/install?id=edgeone-mcp&schema=%7B%22identifier%22%3A...&marketId=higress
209
+ * ```
210
+ */
package/changelog/v1.json CHANGED
@@ -1,4 +1,25 @@
1
1
  [
2
+ {
3
+ "children": {
4
+ "features": [
5
+ "Support mcp plugin install from web."
6
+ ]
7
+ },
8
+ "date": "2025-08-06",
9
+ "version": "1.110.0"
10
+ },
11
+ {
12
+ "children": {
13
+ "fixes": [
14
+ "Fix ollama model output without thinking."
15
+ ],
16
+ "improvements": [
17
+ "Add Claude Opus 4.1 model, update i18n."
18
+ ]
19
+ },
20
+ "date": "2025-08-06",
21
+ "version": "1.109.1"
22
+ },
2
23
  {
3
24
  "children": {
4
25
  "features": [
@@ -1475,6 +1475,12 @@
1475
1475
  "gpt-image-1": {
1476
1476
  "description": "نموذج توليد الصور متعدد الوسائط الأصلي من ChatGPT"
1477
1477
  },
1478
+ "gpt-oss": {
1479
+ "description": "GPT-OSS 20B هو نموذج لغة كبير مفتوح المصدر أصدرته OpenAI، يستخدم تقنية التكميم MXFP4، ومناسب للتشغيل على وحدات معالجة الرسومات الاستهلاكية المتقدمة أو أجهزة Mac بمعالج Apple Silicon. يتميز هذا النموذج بأداء ممتاز في توليد المحادثات، وكتابة الأكواد، ومهام الاستدلال، ويدعم استدعاء الدوال واستخدام الأدوات."
1480
+ },
1481
+ "gpt-oss:120b": {
1482
+ "description": "GPT-OSS 120B هو نموذج لغة كبير مفتوح المصدر أصدرته OpenAI، يستخدم تقنية التكميم MXFP4، ويعتبر نموذجًا رائدًا. يتطلب تشغيله بيئة متعددة وحدات معالجة الرسومات أو محطة عمل عالية الأداء، ويتميز بأداء متفوق في الاستدلال المعقد، وتوليد الأكواد، ومعالجة اللغات المتعددة، ويدعم استدعاء الدوال المتقدمة وتكامل الأدوات."
1483
+ },
1478
1484
  "grok-2-1212": {
1479
1485
  "description": "لقد تم تحسين هذا النموذج في الدقة، والامتثال للتعليمات، والقدرة على التعامل مع لغات متعددة."
1480
1486
  },