diff --git a/src/main/presenter/configPresenter/index.ts b/src/main/presenter/configPresenter/index.ts index 6dada2d34..4d248ce53 100644 --- a/src/main/presenter/configPresenter/index.ts +++ b/src/main/presenter/configPresenter/index.ts @@ -1166,6 +1166,34 @@ export class ConfigPresenter implements IConfigPresenter { newConfigs ) } + + // 批量导入MCP服务器 + async batchImportMcpServers( + servers: Array<{ + name: string + description: string + package: string + version?: string + type?: any + args?: string[] + env?: Record + enabled?: boolean + source?: string + [key: string]: unknown + }>, + options: { + skipExisting?: boolean + enableByDefault?: boolean + overwriteExisting?: boolean + } = {} + ): Promise<{ imported: number; skipped: number; errors: string[] }> { + return this.mcpConfHelper.batchImportMcpServers(servers, options) + } + + // 根据包名查找服务器 + async findMcpServerByPackage(packageName: string): Promise { + return this.mcpConfHelper.findServerByPackage(packageName) + } } export { defaultShortcutKey } from './shortcutKeySettings' diff --git a/src/main/presenter/configPresenter/mcpConfHelper.ts b/src/main/presenter/configPresenter/mcpConfHelper.ts index 593eb211a..06399b9ae 100644 --- a/src/main/presenter/configPresenter/mcpConfHelper.ts +++ b/src/main/presenter/configPresenter/mcpConfHelper.ts @@ -26,6 +26,23 @@ interface IMcpSettings { } export type MCPServerType = 'stdio' | 'sse' | 'inmemory' | 'http' +// Extended MCP server config with additional properties for ModelScope sync +export interface ExtendedMCPServerConfig { + name: string + description: string + args: string[] + env: Record + enabled: boolean + type: MCPServerType + package?: string + version?: string + source?: string + logo_url?: string + publisher?: string + tags?: string[] + view_count?: number +} + // 检查当前系统平台 function isMacOS(): boolean { return process.platform === 'darwin' @@ -624,6 +641,158 @@ export class McpConfHelper { }) } + /** + * Batch import MCP servers from external source (like ModelScope) + * @param servers - Array of MCP server configs to import + * @param options - Import options + * @returns Promise<{ imported: number; skipped: number; errors: string[] }> + */ + async batchImportMcpServers( + servers: Array<{ + name: string + description: string + package: string + version?: string + type?: MCPServerType + args?: string[] + env?: Record + enabled?: boolean + source?: string + [key: string]: unknown + }>, + options: { + skipExisting?: boolean + enableByDefault?: boolean + overwriteExisting?: boolean + } = {} + ): Promise<{ imported: number; skipped: number; errors: string[] }> { + const { skipExisting = true, enableByDefault = false, overwriteExisting = false } = options + const result = { + imported: 0, + skipped: 0, + errors: [] as string[] + } + + const existingServers = await this.getMcpServers() + + for (const serverConfig of servers) { + try { + // Generate unique server name based on package name + const serverName = this.generateUniqueServerName(serverConfig.package, existingServers) + const existingServer = existingServers[serverName] + + // Check if server already exists + if (existingServer && !overwriteExisting) { + if (skipExisting) { + console.log(`Skipping existing MCP server: ${serverName}`) + result.skipped++ + continue + } else { + result.errors.push(`Server ${serverName} already exists`) + continue + } + } + + // Create MCP server config + const mcpConfig: ExtendedMCPServerConfig = { + name: serverConfig.name, + description: serverConfig.description, + args: serverConfig.args || [], + env: serverConfig.env || {}, + enabled: serverConfig.enabled ?? enableByDefault, + type: (serverConfig.type as MCPServerType) || 'stdio', + package: serverConfig.package, + version: serverConfig.version || 'latest', + source: serverConfig.source as string | undefined, + logo_url: serverConfig.logo_url as string | undefined, + publisher: serverConfig.publisher as string | undefined, + tags: serverConfig.tags as string[] | undefined, + view_count: serverConfig.view_count as number | undefined + } + + // Add or update the server + const success = await this.addMcpServer(serverName, mcpConfig as unknown as MCPServerConfig) + if (success || overwriteExisting) { + if (existingServer && overwriteExisting) { + await this.updateMcpServer(serverName, mcpConfig as unknown as Partial) + console.log(`Updated MCP server: ${serverName}`) + } else { + console.log(`Imported MCP server: ${serverName}`) + } + result.imported++ + } else { + result.errors.push(`Failed to import server: ${serverName}`) + } + } catch (error) { + const errorMsg = `Error importing server ${serverConfig.name}: ${error instanceof Error ? error.message : String(error)}` + console.error(errorMsg) + result.errors.push(errorMsg) + } + } + + console.log( + `MCP batch import completed. Imported: ${result.imported}, Skipped: ${result.skipped}, Errors: ${result.errors.length}` + ) + + // Emit event to notify about the import + eventBus.sendToRenderer(MCP_EVENTS.CONFIG_CHANGED, SendTarget.ALL_WINDOWS, { + action: 'batch_import', + result + }) + + return result + } + + /** + * Generate a unique server name based on package name + * @param packageName - The package name to base the server name on + * @param existingServers - Existing servers to check against + * @returns Unique server name + */ + private generateUniqueServerName( + packageName: string, + existingServers: Record + ): string { + // Clean up package name to create a suitable server name + let baseName = packageName + .replace(/[@/]/g, '-') + .replace(/[^a-zA-Z0-9-_]/g, '') + .toLowerCase() + + // If the base name doesn't exist, use it directly + if (!existingServers[baseName]) { + return baseName + } + + // If it exists, append a number suffix + let counter = 1 + let uniqueName = `${baseName}-${counter}` + while (existingServers[uniqueName]) { + counter++ + uniqueName = `${baseName}-${counter}` + } + + return uniqueName + } + + /** + * Check if a server with given package already exists + * @param packageName - Package name to check + * @returns Promise - Returns server name if exists, null otherwise + */ + async findServerByPackage(packageName: string): Promise { + const servers = await this.getMcpServers() + + for (const [serverName, config] of Object.entries(servers)) { + const extendedConfig = config as unknown as ExtendedMCPServerConfig + if (extendedConfig.package === packageName) { + return serverName + } + } + + return null + } + public onUpgrade(oldVersion: string | undefined): void { console.log('onUpgrade', oldVersion) if (oldVersion && compare(oldVersion, '0.0.12', '<=')) { diff --git a/src/main/presenter/configPresenter/providers.ts b/src/main/presenter/configPresenter/providers.ts index 32c2df736..b3485ff15 100644 --- a/src/main/presenter/configPresenter/providers.ts +++ b/src/main/presenter/configPresenter/providers.ts @@ -562,5 +562,20 @@ export const DEFAULT_PROVIDERS: LLM_PROVIDER_BASE[] = [ defaultBaseUrl: 'https://your-resource-name.openai.azure.com/openai/deployments/your-deployment-name' } + }, + { + id: 'modelscope', + name: 'ModelScope', + apiType: 'openai', + apiKey: '', + baseUrl: 'https://api-inference.modelscope.cn/v1/', + enable: false, + websites: { + official: 'https://modelscope.cn/', + apiKey: 'https://modelscope.cn/my/myaccesstoken', + docs: 'https://modelscope.cn/docs/modelscope_agent/api_service', + models: 'https://modelscope.cn/models', + defaultBaseUrl: 'https://api-inference.modelscope.cn/v1/' + } } ] diff --git a/src/main/presenter/llmProviderPresenter/index.ts b/src/main/presenter/llmProviderPresenter/index.ts index 0cc2a5b46..33b76b575 100644 --- a/src/main/presenter/llmProviderPresenter/index.ts +++ b/src/main/presenter/llmProviderPresenter/index.ts @@ -8,7 +8,9 @@ import { ChatMessage, LLMAgentEvent, KeyStatus, - LLM_EMBEDDING_ATTRS + LLM_EMBEDDING_ATTRS, + ModelScopeMcpSyncOptions, + ModelScopeMcpSyncResult } from '@shared/presenter' import { BaseLLMProvider } from './baseProvider' import { OpenAIProvider } from './providers/openAIProvider' @@ -38,6 +40,7 @@ import { OpenRouterProvider } from './providers/openRouterProvider' import { MinimaxProvider } from './providers/minimaxProvider' import { AihubmixProvider } from './providers/aihubmixProvider' import { _302AIProvider } from './providers/_302AIProvider' +import { ModelscopeProvider } from './providers/modelscopeProvider' // 速率限制配置接口 interface RateLimitConfig { @@ -167,6 +170,9 @@ export class LLMProviderPresenter implements ILlmProviderPresenter { if (provider.id === 'aihubmix') { return new AihubmixProvider(provider, this.configPresenter) } + if (provider.id === 'modelscope') { + return new ModelscopeProvider(provider, this.configPresenter) + } switch (provider.apiType) { case 'minimax': return new OpenAIProvider(provider, this.configPresenter) @@ -1599,4 +1605,139 @@ export class LLMProviderPresenter implements ILlmProviderPresenter { } } } + + /** + * Sync MCP servers from ModelScope and import them to local configuration + * @param providerId - Provider ID (should be 'modelscope') + * @param syncOptions - Simplified sync options + * @returns Promise with sync result statistics + */ + async syncModelScopeMcpServers( + providerId: string, + syncOptions?: ModelScopeMcpSyncOptions + ): Promise { + console.log(`[ModelScope MCP Sync] Starting sync for provider: ${providerId}`) + console.log(`[ModelScope MCP Sync] Sync options:`, syncOptions) + + if (providerId !== 'modelscope') { + const error = 'MCP sync is only supported for ModelScope provider' + console.error(`[ModelScope MCP Sync] Error: ${error}`) + throw new Error(error) + } + + const provider = this.getProviderInstance(providerId) + + // Type check for ModelscopeProvider + if (provider.constructor.name !== 'ModelscopeProvider') { + const error = 'Provider is not a ModelScope provider instance' + console.error(`[ModelScope MCP Sync] Error: ${error}`) + throw new Error(error) + } + + const result: ModelScopeMcpSyncResult = { + imported: 0, + skipped: 0, + errors: [] + } + + try { + // Create async task to prevent blocking main thread + const syncTask = async () => { + console.log(`[ModelScope MCP Sync] Fetching MCP servers from ModelScope API...`) + + // Call ModelscopeProvider to fetch MCP servers + const modelscopeProvider = provider as any + const mcpResponse = await modelscopeProvider.syncMcpServers(syncOptions) + + if (!mcpResponse || !mcpResponse.success || !mcpResponse.data?.mcp_server_list) { + const errorMsg = 'Invalid response from ModelScope MCP API' + console.error(`[ModelScope MCP Sync] ${errorMsg}`, mcpResponse) + result.errors.push(errorMsg) + return result + } + + const mcpServers = mcpResponse.data.mcp_server_list + console.log(`[ModelScope MCP Sync] Fetched ${mcpServers.length} MCP servers from API`) + + // Convert ModelScope operational MCP servers to internal format + const convertedServers = mcpServers + .map((server: any) => { + try { + // Check if operational URLs are available + if (!server.operational_urls || server.operational_urls.length === 0) { + const errorMsg = `No operational URLs found for server ${server.id}` + console.warn(`[ModelScope MCP Sync] ${errorMsg}`) + result.errors.push(errorMsg) + return null + } + + // Use ModelScope provider's conversion method for consistency + const modelscopeProvider = provider as any + const converted = modelscopeProvider.convertMcpServerToConfig(server) + + console.log( + `[ModelScope MCP Sync] Converted operational server: ${converted.displayName} (${converted.name})` + ) + return converted + } catch (conversionError) { + const errorMsg = `Failed to convert server ${server.name || server.id}: ${conversionError instanceof Error ? conversionError.message : String(conversionError)}` + console.error(`[ModelScope MCP Sync] ${errorMsg}`) + result.errors.push(errorMsg) + return null + } + }) + .filter((server: any) => server !== null) + + console.log( + `[ModelScope MCP Sync] Successfully converted ${convertedServers.length} servers` + ) + + // Import servers to configuration using configPresenter + for (const serverConfig of convertedServers) { + try { + const existingServers = await this.configPresenter.getMcpServers() + + // Check if server already exists + if (existingServers[serverConfig.name]) { + console.log( + `[ModelScope MCP Sync] Server ${serverConfig.name} already exists, skipping` + ) + result.skipped++ + continue + } + + // Add server to configuration + const success = await this.configPresenter.addMcpServer(serverConfig.name, serverConfig) + if (success) { + console.log( + `[ModelScope MCP Sync] Successfully imported server: ${serverConfig.name}` + ) + result.imported++ + } else { + const errorMsg = `Failed to add server ${serverConfig.name} to configuration` + console.error(`[ModelScope MCP Sync] ${errorMsg}`) + result.errors.push(errorMsg) + } + } catch (importError) { + const errorMsg = `Failed to import server ${serverConfig.name}: ${importError instanceof Error ? importError.message : String(importError)}` + console.error(`[ModelScope MCP Sync] ${errorMsg}`) + result.errors.push(errorMsg) + } + } + + console.log( + `[ModelScope MCP Sync] Sync completed. Imported: ${result.imported}, Skipped: ${result.skipped}, Errors: ${result.errors.length}` + ) + return result + } + + // Execute async without blocking + return await syncTask() + } catch (error) { + const errorMsg = `ModelScope MCP sync failed: ${error instanceof Error ? error.message : String(error)}` + console.error(`[ModelScope MCP Sync] ${errorMsg}`) + result.errors.push(errorMsg) + return result + } + } } diff --git a/src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts b/src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts new file mode 100644 index 000000000..e6b4df50b --- /dev/null +++ b/src/main/presenter/llmProviderPresenter/providers/modelscopeProvider.ts @@ -0,0 +1,338 @@ +import { LLM_PROVIDER, LLMResponse, ChatMessage, KeyStatus } from '@shared/presenter' +import { OpenAICompatibleProvider } from './openAICompatibleProvider' +import { ConfigPresenter } from '../../configPresenter' + +// Define interface for ModelScope MCP API response +interface ModelScopeMcpServerResponse { + code: number + data: { + mcp_server_list: ModelScopeMcpServer[] + total_count: number + } + message: string + request_id: string + success: boolean +} + +// Define interface for ModelScope MCP server (updated for operational API) +interface ModelScopeMcpServer { + name: string + description: string + id: string + chinese_name?: string // Chinese name field + logo_url: string + operational_urls: Array<{ + id: string + url: string + }> + tags: string[] + locales: { + zh: { + name: string + description: string + } + en: { + name: string + description: string + } + } +} + +export class ModelscopeProvider extends OpenAICompatibleProvider { + constructor(provider: LLM_PROVIDER, configPresenter: ConfigPresenter) { + super(provider, configPresenter) + } + + async completions( + messages: ChatMessage[], + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion(messages, modelId, temperature, maxTokens) + } + + async summaries( + text: string, + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion( + [ + { + role: 'user', + content: `You need to summarize the user's conversation into a title of no more than 10 words, with the title language matching the user's primary language, without using punctuation or other special symbols:\n${text}` + } + ], + modelId, + temperature, + maxTokens + ) + } + + async generateText( + prompt: string, + modelId: string, + temperature?: number, + maxTokens?: number + ): Promise { + return this.openAICompletion( + [ + { + role: 'user', + content: prompt + } + ], + modelId, + temperature, + maxTokens + ) + } + + /** + * Get current API key status from ModelScope + * @returns Promise API key status information + */ + public async getKeyStatus(): Promise { + if (!this.provider.apiKey) { + throw new Error('API key is required') + } + + try { + // Use models endpoint to check API key validity + const response = await this.openai.models.list({ timeout: 10000 }) + + return { + limit_remaining: 'Available', + remainNum: response.data?.length || 0 + } + } catch (error) { + console.error('ModelScope API key check failed:', error) + throw new Error( + `ModelScope API key check failed: ${error instanceof Error ? error.message : String(error)}` + ) + } + } + + /** + * Override check method to use ModelScope's API validation + * @returns Promise<{ isOk: boolean; errorMsg: string | null }> + */ + public async check(): Promise<{ isOk: boolean; errorMsg: string | null }> { + try { + await this.getKeyStatus() + return { isOk: true, errorMsg: null } + } catch (error: unknown) { + let errorMessage = 'An unknown error occurred during ModelScope API key check.' + if (error instanceof Error) { + errorMessage = error.message + } else if (typeof error === 'string') { + errorMessage = error + } + + console.error('ModelScope API key check failed:', error) + return { isOk: false, errorMsg: errorMessage } + } + } + + /** + * Sync operational MCP servers from ModelScope API + * @param _options - Sync options including filters (currently not used by operational API) + * @returns Promise MCP servers response + */ + public async syncMcpServers(_options?: { + page_number?: number + page_size?: number + }): Promise { + if (!this.provider.apiKey) { + throw new Error('API key is required for MCP sync') + } + + try { + // Use the operational API endpoint - GET request, no body needed + const response = await fetch('https://www.modelscope.cn/openapi/v1/mcp/servers/operational', { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + Authorization: `Bearer ${this.provider.apiKey}` + }, + signal: AbortSignal.timeout(30000) // 30 second timeout + }) + + // Handle authentication errors + if (response.status === 401 || response.status === 403) { + throw new Error('ModelScope MCP sync unauthorized: Invalid or expired API key') + } + + // Handle server errors + if (response.status === 500 || !response.ok) { + const errorText = await response.text() + throw new Error( + `ModelScope MCP sync failed: ${response.status} ${response.statusText} - ${errorText}` + ) + } + + const data: ModelScopeMcpServerResponse = await response.json() + + if (!data.success) { + throw new Error(`ModelScope MCP sync failed: ${data.message}`) + } + + console.log( + `Successfully fetched ${data.data.mcp_server_list.length} operational MCP servers from ModelScope` + ) + return data + } catch (error) { + console.error('ModelScope MCP sync error:', error) + throw error + } + } + + /** + * Convert ModelScope operational MCP server to internal MCP server config format + * @param mcpServer - ModelScope MCP server data + * @returns Internal MCP server config + */ + public convertMcpServerToConfig(mcpServer: ModelScopeMcpServer) { + // Check if operational URLs are available + if (!mcpServer.operational_urls || mcpServer.operational_urls.length === 0) { + throw new Error(`No operational URLs found for server ${mcpServer.id}`) + } + + // Use the first operational URL + const baseUrl = mcpServer.operational_urls[0].url + + // Generate random emoji for icon + const emojis = [ + '🔧', + '⚡', + '🚀', + '🔨', + '⚙️', + '🛠️', + '🔥', + '💡', + '⭐', + '🎯', + '🎨', + '🔮', + '💎', + '🎪', + '🎭', + '🎨', + '🔬', + '📱', + '💻', + '🖥️', + '⌨️', + '🖱️', + '📡', + '🔊', + '📢', + '📣', + '📯', + '🔔', + '🔕', + '📻', + '📺', + '📷', + '📹', + '🎥', + '📽️', + '🔍', + '🔎', + '💰', + '💳', + '💸', + '💵', + '🎲', + '🃏', + '🎮', + '🕹️', + '🎯', + '🎳', + '🎨', + '🖌️', + '🖍️', + '📝', + '✏️', + '📏', + '📐', + '📌', + '📍', + '🗂️', + '📂', + '📁', + '📰', + '📄', + '📃', + '📜', + '📋', + '📊', + '📈', + '📉', + '📦', + '📫', + '📪', + '📬', + '📭', + '📮', + '🗳️', + '✉️', + '📧', + '📨', + '📩', + '📤', + '📥', + '📬', + '📭', + '📮', + '🗂️', + '📂', + '📁', + '🗄️', + '🗃️', + '📋', + '📑', + '📄', + '📃', + '📰', + '🗞️', + '📜', + '🔖' + ] + const randomEmoji = emojis[Math.floor(Math.random() * emojis.length)] + + // Get display name: chinese_name first, then id + const displayName = mcpServer.chinese_name || mcpServer.id + + return { + name: `@modelscope/${mcpServer.id}`, // Use ModelScope ID format + description: + mcpServer.locales?.zh?.description || + mcpServer.description || + `ModelScope MCP Server: ${displayName}`, + command: '', // Not needed for SSE type + args: [], // Not needed for SSE type + env: {}, + type: 'sse' as const, // SSE type for operational servers + baseUrl: baseUrl, // Use operational URL + enabled: false, // Default to disabled for safety + source: 'modelscope' as const, + // Additional metadata + descriptions: + mcpServer.locales?.zh?.description || + mcpServer.description || + `ModelScope MCP Server: ${displayName}`, + icons: randomEmoji, // Random emoji instead of URL + provider: 'ModelScope', + providerUrl: `https://www.modelscope.cn/mcp/servers/@${mcpServer.id}`, + logoUrl: '', // No longer using logo URL + tags: mcpServer.tags || [], + // Store original data for reference + originalId: mcpServer.id, + displayName: displayName + } + } +} diff --git a/src/renderer/src/components/icons/ModelIcon.vue b/src/renderer/src/components/icons/ModelIcon.vue index 2d00f3c58..2ef7c4db1 100644 --- a/src/renderer/src/components/icons/ModelIcon.vue +++ b/src/renderer/src/components/icons/ModelIcon.vue @@ -57,8 +57,10 @@ import defaultIcon from '@/assets/logo.png?url' import metaColorIcon from '@/assets/llm-icons/meta.svg?url' import lmstudioColorIcon from '@/assets/llm-icons/lmstudio.svg?url' import _302aiIcon from '@/assets/llm-icons/302ai.svg?url' +import modelscopeColorIcon from '@/assets/llm-icons/modelscope-color.svg?url' // 导入所有图标 const icons = { + modelscope: modelscopeColorIcon, '302ai': _302aiIcon, aihubmix: aihubmixColorIcon, dashscope: dashscopeColorIcon, diff --git a/src/renderer/src/components/mcp-config/components/McpToolPanel.vue b/src/renderer/src/components/mcp-config/components/McpToolPanel.vue index b4861b3cf..1d6d71ba1 100644 --- a/src/renderer/src/components/mcp-config/components/McpToolPanel.vue +++ b/src/renderer/src/components/mcp-config/components/McpToolPanel.vue @@ -19,6 +19,7 @@ import { SelectValue } from '@/components/ui/select' import { useMcpStore } from '@/stores/mcp' +import { useMediaQuery } from '@vueuse/core' import { useI18n } from 'vue-i18n' import McpJsonViewer from './McpJsonViewer.vue' import type { MCPToolDefinition } from '@shared/presenter' @@ -52,6 +53,14 @@ const serverTools = computed(() => { return mcpStore.tools.filter((tool) => tool.server.name === props.serverName) }) +// 屏幕断点:lg 及以上 +const isLgScreen = useMediaQuery('(min-width: 1024px)') + +// 顶部下拉是否显示:小屏时显示;或大屏但左侧列表不可用(无工具)时显示 +const showTopSelector = computed(() => { + return !isLgScreen.value || serverTools.value.length === 0 +}) + watch(open, (newOpen) => { if (newOpen) { selectedToolName.value = '' @@ -161,8 +170,8 @@ const selectTool = (tool: MCPToolDefinition) => {
- -
+ +
+ + + + + +
+ + +
+ + +
+ + + + + +
+ +
+
+ + +
+ + {{ t('settings.provider.modelscope.mcpSync.imported', { count: syncResult.imported }) }} + + + {{ t('settings.provider.modelscope.mcpSync.skipped', { count: syncResult.skipped }) }} + + + {{ + t('settings.provider.modelscope.mcpSync.errors', { count: syncResult.errors.length }) + }} + +
+ + +
+

{{ errorMessage }}

+
+ + +
+

+ {{ t('settings.provider.modelscope.mcpSync.errorDetails') }} +

+
+
+ {{ error }} +
+
+
+
+ + + + diff --git a/src/renderer/src/i18n/en-US/settings.json b/src/renderer/src/i18n/en-US/settings.json index f3884ff1f..1984cb34d 100644 --- a/src/renderer/src/i18n/en-US/settings.json +++ b/src/renderer/src/i18n/en-US/settings.json @@ -266,7 +266,10 @@ "failed": "Verification failed", "success": "Verification successful", "failedDesc": "API key or configuration verification failed, please check your configuration", - "successDesc": "API key and configuration verified successfully, ready to use" + "successDesc": "API key and configuration verified successfully, ready to use", + "connectionError": "Connection error, please check the network connection and API address", + "serverError": "Server error, please try again later", + "unauthorized": "Authentication failed, API Key is invalid or expired" }, "addCustomProvider": { "title": "Add Custom Provider", @@ -351,6 +354,58 @@ "modelRunning": "The model is running", "modelRunningDesc": "Please stop the model {model} first and then delete it." }, + "modelscope": { + "mcpSync": { + "title": "Sync MCP Services", + "description": "Sync MCP servers from ModelScope to local configuration, allowing quick addition of common MCP tools.", + "sync": "Start Sync", + "syncing": "Syncing...", + "pageSize": "Page Size", + "imported": "Imported {count} services", + "skipped": "Skipped {count} services", + "errors": "{count} errors", + "errorDetails": "Error Details", + "noApiKey": "Please configure ModelScope API Key first", + "noServersFound": "No available MCP services found", + "authenticationFailed": "Authentication failed, please check API Key", + "convertingServers": "Converting server configuration...", + "fetchingServers": "Getting the list of MCP servers...", + "importingServers": "Importing server configuration...", + "noOperationalUrls": "No available operating address found", + "pageNumber": "page number", + "pageNumberPlaceholder": "Please enter the page number", + "serverAlreadyExists": "The server already exists, skip import", + "syncComplete": "Synchronous completion", + "invalidServerData": "Invalid server data" + }, + "apiKey": "API Key", + "apiKeyHelper": "Get your API Key in the ModelScope console", + "apiKeyPlaceholder": "Please enter ModelScope API Key", + "baseUrl": "API Address", + "baseUrlHelper": "ModelScope API service address", + "connected": "Connected", + "connecting": "Connecting...", + "description": "ModelScope is a model-as-a-service sharing platform launched by Alibaba Damo Academy", + "details": { + "apiConfig": "API Configuration", + "mcpSync": "MCP Synchronization", + "modelManagement": "Model Management", + "operationalDescription": "Synchronize MCP servers that can be used directly on the ModelScope platform", + "operationalServers": "Operating a server", + "rateLimitConfig": "Rate limit configuration", + "safetySettings": "Security settings", + "specialConfig": "Special configuration", + "syncFromModelScope": "Sync from ModelScope", + "title": "Provider settings details" + }, + "invalidKey": "Invalid API Key", + "keyRequired": "Please enter API Key", + "name": "ModelScope", + "networkError": "Network connection error", + "notConnected": "Not connected", + "verifyFailed": "Verification failed", + "verifySuccess": "Verification is successful" + }, "anthropicApiKeyTip": "Please go to Anthropic Console to get your API Key", "anthropicConnected": "Anthropic connected", "anthropicNotConnected": "Anthropic not connected", @@ -374,7 +429,13 @@ "manageModels": "Manage Models", "anthropicOAuthActiveTip": "OAuth authentication is enabled, you can use Anthropic services directly", "oauthVerifySuccess": "OAuth connection verified successfully", - "oauthVerifyFailed": "OAuth connection verification failed" + "oauthVerifyFailed": "OAuth connection verification failed", + "configurationSaved": "Configuration saved", + "configurationUpdated": "Configuration updated", + "dataRefreshed": "Data has been refreshed", + "operationFailed": "Operation failed", + "operationSuccess": "Operation is successful", + "settingsApplied": "Settings applied" }, "knowledgeBase": { "title": "Knowledge Base Settings", diff --git a/src/renderer/src/i18n/fa-IR/settings.json b/src/renderer/src/i18n/fa-IR/settings.json index db8c2cf2c..87dd3fe13 100644 --- a/src/renderer/src/i18n/fa-IR/settings.json +++ b/src/renderer/src/i18n/fa-IR/settings.json @@ -266,7 +266,10 @@ "failed": "راستی‌آزمایی ناموفق", "success": "راستی‌آزمایی موفق", "failedDesc": "راستی‌آزمایی کلید API یا پیکربندی ناموفق بود، لطفاً تنظیمات را بررسی کنید", - "successDesc": "کلید API و پیکربندی با موفقیت راستی‌آزمایی شد، آماده استفاده است" + "successDesc": "کلید API و پیکربندی با موفقیت راستی‌آزمایی شد، آماده استفاده است", + "connectionError": "خطای اتصال ، لطفا اتصال شبکه و آدرس API را بررسی کنید", + "serverError": "خطای سرور ، لطفاً بعداً دوباره امتحان کنید", + "unauthorized": "احراز هویت انجام نشد ، کلید API نامعتبر یا منقضی شده است" }, "addCustomProvider": { "title": "افزودن فراهم‌کننده دلخواه", @@ -374,7 +377,65 @@ "manageModels": "مدیریت مدل‌ها", "anthropicOAuthActiveTip": "احراز هویت OAuth فعال است، می‌توانید مستقیماً از سرویس‌های Anthropic استفاده کنید", "oauthVerifySuccess": "اتصال OAuth با موفقیت تأیید شد", - "oauthVerifyFailed": "تأیید اتصال OAuth ناموفق بود" + "oauthVerifyFailed": "تأیید اتصال OAuth ناموفق بود", + "configurationSaved": "پیکربندی ذخیره شده", + "configurationUpdated": "پیکربندی به روز شد", + "dataRefreshed": "داده ها تازه شده است", + "modelscope": { + "apiKey": "کلید API", + "apiKeyHelper": "کلید API خود را در کنسول ModelCope دریافت کنید", + "apiKeyPlaceholder": "لطفاً کلید API Modelcope را وارد کنید", + "baseUrl": "آدرس API", + "baseUrlHelper": "آدرس خدمات API Modelcope", + "connected": "متصل", + "connecting": "اتصال ...", + "description": "Modelcope یک بستر اشتراک گذاری مدل به عنوان یک سرویس است که توسط آکادمی Alibaba Damo راه اندازی شده است", + "details": { + "apiConfig": "پیکربندی API", + "mcpSync": "همگام سازی MCP", + "modelManagement": "مدیریت مدل", + "operationalDescription": "سرورهای MCP را همگام سازی کنید که می توانند مستقیماً در سیستم عامل ModelCope استفاده شوند", + "operationalServers": "کار کردن یک سرور", + "rateLimitConfig": "پیکربندی حد نرخ", + "safetySettings": "تنظیمات امنیتی", + "specialConfig": "پیکربندی خاص", + "syncFromModelScope": "همگام سازی از Modelcope", + "title": "جزئیات تنظیمات ارائه دهنده" + }, + "invalidKey": "کلید API نامعتبر", + "keyRequired": "لطفا کلید API را وارد کنید", + "mcpSync": { + "authenticationFailed": "احراز هویت انجام نشد ، لطفاً کلید API را بررسی کنید", + "convertingServers": "تبدیل پیکربندی سرور ...", + "description": "همگام سازی یک سرور MCP از ModelScope به تنظیمات محلی به شما امکان می دهد تا به سرعت ابزارهای MCP متداول را اضافه کنید. کلیه خدمات به طور پیش فرض غیرفعال می شوند و پس از وارد کردن می توانند به صورت دستی فعال شوند.", + "errorDetails": "جزئیات خطا", + "errors": "خطا {تعداد}", + "fetchingServers": "دریافت لیست سرورهای MCP ...", + "imported": "{تعداد خدمات وارد شده است", + "importingServers": "وارد کردن پیکربندی سرور ...", + "invalidServerData": "داده های سرور نامعتبر", + "noApiKey": "لطفاً ابتدا کلید API Modelcope را پیکربندی کنید", + "noOperationalUrls": "هیچ آدرس عملیاتی موجود یافت نمی شود", + "noServersFound": "هیچ سرویس MCP در دسترس یافت نشد", + "pageNumber": "شماره صفحه", + "pageNumberPlaceholder": "لطفا شماره صفحه را وارد کنید", + "pageSize": "مقدار در هر صفحه", + "serverAlreadyExists": "سرور در حال حاضر وجود دارد ، واردات را پرش کنید", + "skipped": "خدمات SKIP {COUNT", + "sync": "همگام سازی را شروع کنید", + "syncComplete": "اتمام همزمان", + "syncing": "هماهنگ سازی ...", + "title": "همگام سازی خدمات MCP" + }, + "name": "مدلهای مدل", + "networkError": "خطای اتصال شبکه", + "notConnected": "متصل نیست", + "verifyFailed": "تأیید انجام نشد", + "verifySuccess": "تأیید موفقیت آمیز است" + }, + "operationFailed": "عملیات شکست خورد", + "operationSuccess": "عملیات موفقیت آمیز است", + "settingsApplied": "تنظیمات اعمال شده" }, "knowledgeBase": { "title": "تنظیمات پایگاه دانش", diff --git a/src/renderer/src/i18n/fr-FR/settings.json b/src/renderer/src/i18n/fr-FR/settings.json index ddd01ab00..375b7ebcb 100644 --- a/src/renderer/src/i18n/fr-FR/settings.json +++ b/src/renderer/src/i18n/fr-FR/settings.json @@ -266,7 +266,10 @@ "failed": "Échec de la vérification", "success": "Vérification réussie", "failedDesc": "La vérification de la clé API ou de la configuration a échoué, veuillez vérifier vos paramètres", - "successDesc": "La clé API et la configuration ont été vérifiées avec succès, prêt à utiliser" + "successDesc": "La clé API et la configuration ont été vérifiées avec succès, prêt à utiliser", + "connectionError": "Erreur de connexion, veuillez vérifier la connexion réseau et l'adresse de l'API", + "serverError": "Erreur du serveur, veuillez réessayer plus tard", + "unauthorized": "Échec de l'authentification, la clé API n'est pas valide ou expirée" }, "addCustomProvider": { "title": "Ajouter un fournisseur personnalisé", @@ -374,7 +377,65 @@ "manageModels": "Gérer les modèles", "anthropicOAuthActiveTip": "L'authentification OAuth est activée, vous pouvez utiliser les services Anthropic directement", "oauthVerifySuccess": "Connexion OAuth vérifiée avec succès", - "oauthVerifyFailed": "Échec de la vérification de la connexion OAuth" + "oauthVerifyFailed": "Échec de la vérification de la connexion OAuth", + "configurationSaved": "Configuration enregistrée", + "configurationUpdated": "Configuration mise à jour", + "dataRefreshed": "Les données ont été rafraîchies", + "modelscope": { + "apiKey": "Clé API", + "apiKeyHelper": "Obtenez votre clé API dans la console Modelcope", + "apiKeyPlaceholder": "Veuillez saisir la clé de l'API Modelscope", + "baseUrl": "Adresse API", + "baseUrlHelper": "Adresse du service API Modelcope", + "connected": "Connecté", + "connecting": "De liaison...", + "description": "Modelcope est une plate-forme de partage modèle en tant que service lancée par Alibaba Damo Academy", + "details": { + "apiConfig": "Configuration de l'API", + "mcpSync": "Synchronisation MCP", + "modelManagement": "Gestion des modèles", + "operationalDescription": "Synchroniser les serveurs MCP qui peuvent être utilisés directement sur la plate-forme Modelcope", + "operationalServers": "Exploitation d'un serveur", + "rateLimitConfig": "Configuration de la limite de taux", + "safetySettings": "Paramètres de sécurité", + "specialConfig": "Configuration spéciale", + "syncFromModelScope": "Synchronisation de Modelscope", + "title": "Détails des paramètres du fournisseur" + }, + "invalidKey": "Clé API non valide", + "keyRequired": "Veuillez saisir la clé de l'API", + "mcpSync": { + "authenticationFailed": "Échec de l'authentification, veuillez vérifier la clé de l'API", + "convertingServers": "Conversion de la configuration du serveur ...", + "description": "La synchronisation d'un serveur MCP de Modelcope aux configurations locales vous permet d'ajouter rapidement des outils MCP couramment utilisés. Tous les services sont désactivés par défaut et peuvent être activés manuellement après l'importation.", + "errorDetails": "Détails d'erreur", + "errors": "Erreur {count}", + "fetchingServers": "Obtenir la liste des serveurs MCP ...", + "imported": "{comte} Les services ont été importés", + "importingServers": "Configuration d'importation de serveur ...", + "invalidServerData": "Données de serveur non valides", + "noApiKey": "Veuillez d'abord configurer la clé de l'API Modelcope", + "noOperationalUrls": "Aucune adresse de fonctionnement disponible trouvée", + "noServersFound": "Aucun service MCP disponible trouvé", + "pageNumber": "numéro de page", + "pageNumberPlaceholder": "Veuillez saisir le numéro de page", + "pageSize": "Quantité par page", + "serverAlreadyExists": "Le serveur existe déjà, sautez l'importation", + "skipped": "Skip {count} Services", + "sync": "Commencer à se synchroniser", + "syncComplete": "Achèvement synchrone", + "syncing": "Synchronisation...", + "title": "Synchroniser les services MCP" + }, + "name": "Modelcope", + "networkError": "Erreur de connexion réseau", + "notConnected": "Non connecté", + "verifyFailed": "Échec de la vérification", + "verifySuccess": "La vérification est réussie" + }, + "operationFailed": "L'opération a échoué", + "operationSuccess": "L'opération est réussie", + "settingsApplied": "Paramètres appliqués" }, "knowledgeBase": { "title": "Paramètres de la base de connaissances", diff --git a/src/renderer/src/i18n/ja-JP/settings.json b/src/renderer/src/i18n/ja-JP/settings.json index 948c3f2eb..1ae73a93b 100644 --- a/src/renderer/src/i18n/ja-JP/settings.json +++ b/src/renderer/src/i18n/ja-JP/settings.json @@ -266,7 +266,10 @@ "failed": "検証に失敗しました", "success": "検証に成功しました", "failedDesc": "APIキーまたは設定の検証に失敗しました。設定を確認してください", - "successDesc": "APIキーと設定の検証に成功しました。使用可能です" + "successDesc": "APIキーと設定の検証に成功しました。使用可能です", + "connectionError": "接続エラー、ネットワーク接続とAPIアドレスを確認してください", + "serverError": "サーバーエラー、後でもう一度やり直してください", + "unauthorized": "認証に失敗し、APIキーが無効または期限切れです" }, "addCustomProvider": { "title": "カスタムプロバイダーを追加", @@ -374,7 +377,65 @@ "manageModels": "モデル管理", "anthropicOAuthActiveTip": "OAuth認証が有効になっており、Anthropicサービスを直接使用できます", "oauthVerifySuccess": "OAuth接続の確認が成功しました", - "oauthVerifyFailed": "OAuth接続の確認に失敗しました" + "oauthVerifyFailed": "OAuth接続の確認に失敗しました", + "configurationSaved": "構成が保存されました", + "configurationUpdated": "設定が更新されました", + "dataRefreshed": "データは更新されています", + "modelscope": { + "apiKey": "APIキー", + "apiKeyHelper": "ModelScopeコンソールでAPIキーを取得します", + "apiKeyPlaceholder": "ModelScope APIキーを入力してください", + "baseUrl": "APIアドレス", + "baseUrlHelper": "ModelScope APIサービスアドレス", + "connected": "接続", + "connecting": "接続...", + "description": "ModelScopeは、Alibaba Damo Academyによって開始されたサービスとしてのモデル共有プラットフォームです", + "details": { + "apiConfig": "API構成", + "mcpSync": "MCP同期", + "modelManagement": "モデル管理", + "operationalDescription": "ModelScopeプラットフォームで直接使用できるMCPサーバーを同期する", + "operationalServers": "サーバーの操作", + "rateLimitConfig": "レート制限構成", + "safetySettings": "セキュリティ設定", + "specialConfig": "特別な構成", + "syncFromModelScope": "ModelScopeから同期します", + "title": "プロバイダーの設定の詳細" + }, + "invalidKey": "無効なAPIキー", + "keyRequired": "APIキーを入力してください", + "mcpSync": { + "authenticationFailed": "認証に失敗しました。APIキーを確認してください", + "convertingServers": "サーバー構成の変換...", + "description": "MODESCOPEからローカル構成までMCPサーバーを同期すると、一般的に使用されるMCPツールをすばやく追加できます。すべてのサービスはデフォルトで無効になり、インポート後に手動で有効にすることができます。", + "errorDetails": "エラーの詳細", + "errors": "エラー{count}", + "fetchingServers": "MCPサーバーのリストを取得...", + "imported": "{count}サービスがインポートされています", + "importingServers": "サーバー構成のインポート...", + "invalidServerData": "無効なサーバーデータ", + "noApiKey": "ModelScope APIキーを最初に構成してください", + "noOperationalUrls": "利用可能な操作アドレスは見つかりません", + "noServersFound": "利用可能なMCPサービスは見つかりません", + "pageNumber": "ページ番号", + "pageNumberPlaceholder": "ページ番号を入力してください", + "pageSize": "ページごとの数量", + "serverAlreadyExists": "サーバーはすでに存在し、インポートをスキップします", + "skipped": "Skip {count}サービス", + "sync": "同期を開始します", + "syncComplete": "同期完了", + "syncing": "同期...", + "title": "MCPサービスを同期します" + }, + "name": "ModelScope", + "networkError": "ネットワーク接続エラー", + "notConnected": "接続されていません", + "verifyFailed": "検証に失敗しました", + "verifySuccess": "検証は成功しました" + }, + "operationFailed": "操作に失敗しました", + "operationSuccess": "操作は成功しました", + "settingsApplied": "適用された設定" }, "knowledgeBase": { "title": "ナレッジベース設定", diff --git a/src/renderer/src/i18n/ko-KR/settings.json b/src/renderer/src/i18n/ko-KR/settings.json index e0f8b8028..22e0f732f 100644 --- a/src/renderer/src/i18n/ko-KR/settings.json +++ b/src/renderer/src/i18n/ko-KR/settings.json @@ -265,7 +265,10 @@ "failed": "확인 실패", "success": "확인 성공", "failedDesc": "API 키 또는 설정 확인에 실패했습니다. 설정을 확인해주세요", - "successDesc": "API 키와 설정이 성공적으로 확인되었습니다. 사용 가능합니다" + "successDesc": "API 키와 설정이 성공적으로 확인되었습니다. 사용 가능합니다", + "connectionError": "연결 오류, 네트워크 연결 및 API 주소를 확인하십시오.", + "serverError": "서버 오류, 나중에 다시 시도하십시오", + "unauthorized": "인증 실패, API 키가 유효하지 않거나 만료되었습니다" }, "addCustomProvider": { "title": "커스텀 제공자 추가", @@ -374,7 +377,65 @@ "manageModels": "모델 관리", "anthropicOAuthActiveTip": "OAuth 인증이 활성화되어 있어 Anthropic 서비스를 직접 사용할 수 있습니다", "oauthVerifySuccess": "OAuth 연결 확인 성공", - "oauthVerifyFailed": "OAuth 연결 확인 실패" + "oauthVerifyFailed": "OAuth 연결 확인 실패", + "configurationSaved": "구성 저장", + "configurationUpdated": "구성 업데이트", + "dataRefreshed": "데이터가 새로 고쳐졌습니다", + "modelscope": { + "apiKey": "API 키", + "apiKeyHelper": "ModelScope 콘솔에서 API 키를 얻으십시오", + "apiKeyPlaceholder": "ModelScope API 키를 입력하십시오", + "baseUrl": "API 주소", + "baseUrlHelper": "ModelScope API 서비스 주소", + "connected": "연결", + "connecting": "연결 ...", + "description": "ModelScope는 Alibaba Damo Academy가 시작한 Model-as-A-Service 공유 플랫폼입니다.", + "details": { + "apiConfig": "API 구성", + "mcpSync": "MCP 동기화", + "modelManagement": "모델 관리", + "operationalDescription": "ModelScope 플랫폼에서 직접 사용할 수있는 MCP 서버 동기화", + "operationalServers": "서버 작동", + "rateLimitConfig": "요율 제한 구성", + "safetySettings": "보안 설정", + "specialConfig": "특별 구성", + "syncFromModelScope": "ModelScope에서 동기화됩니다", + "title": "제공자 설정 세부 정보" + }, + "invalidKey": "잘못된 API 키", + "keyRequired": "API 키를 입력하십시오", + "mcpSync": { + "authenticationFailed": "인증 실패, API 키를 확인하십시오", + "convertingServers": "서버 구성 변환 ...", + "description": "Modescope에서 로컬 구성으로 MCP 서버를 동기화하면 일반적으로 사용되는 MCP 도구를 빠르게 추가 할 수 있습니다. 모든 서비스는 기본적으로 비활성화되며 가져온 후 수동으로 활성화 할 수 있습니다.", + "errorDetails": "오류 세부 사항", + "errors": "오류 {count}", + "fetchingServers": "MCP 서버 목록 얻기 ...", + "imported": "{count} 서비스가 가져 왔습니다", + "importingServers": "서버 구성 가져 오기 ...", + "invalidServerData": "잘못된 서버 데이터", + "noApiKey": "먼저 ModelScope API 키를 구성하십시오", + "noOperationalUrls": "사용 가능한 운영 주소가 없습니다", + "noServersFound": "사용 가능한 MCP 서비스가 없습니다", + "pageNumber": "페이지 번호", + "pageNumberPlaceholder": "페이지 번호를 입력하십시오", + "pageSize": "페이지 당 수량", + "serverAlreadyExists": "서버가 이미 존재하고 가져 오기를 건너 뛰십시오", + "skipped": "{count} 서비스를 건너 뛰십시오", + "sync": "동기화를 시작하십시오", + "syncComplete": "동기 완성", + "syncing": "동기화...", + "title": "MCP 서비스 동기화" + }, + "name": "ModelsCope", + "networkError": "네트워크 연결 오류", + "notConnected": "연결되지 않았습니다", + "verifyFailed": "확인이 실패했습니다", + "verifySuccess": "확인이 성공적입니다" + }, + "operationFailed": "작동 실패", + "operationSuccess": "운영이 성공적입니다", + "settingsApplied": "설정이 적용됩니다" }, "knowledgeBase": { "title": "지식 베이스 설정", diff --git a/src/renderer/src/i18n/ru-RU/settings.json b/src/renderer/src/i18n/ru-RU/settings.json index ee8b305da..5ae09d61e 100644 --- a/src/renderer/src/i18n/ru-RU/settings.json +++ b/src/renderer/src/i18n/ru-RU/settings.json @@ -265,7 +265,10 @@ "failed": "Проверка не удалась", "success": "Проверка успешна", "failedDesc": "Проверка API ключа или конфигурации не удалась, проверьте настройки", - "successDesc": "API ключ и конфигурация успешно проверены, готовы к использованию" + "successDesc": "API ключ и конфигурация успешно проверены, готовы к использованию", + "connectionError": "Ошибка соединения, пожалуйста, проверьте сетевое соединение и адрес API", + "serverError": "Ошибка сервера, попробуйте еще раз позже", + "unauthorized": "Аутентификация не удалась, ключ API является недействительным или истекшим" }, "addCustomProvider": { "title": "Добавить пользовательский провайдер", @@ -374,7 +377,65 @@ "manageModels": "Управление моделями", "anthropicOAuthActiveTip": "Аутентификация OAuth включена, вы можете использовать сервисы Anthropic напрямую", "oauthVerifySuccess": "Соединение OAuth успешно проверено", - "oauthVerifyFailed": "Ошибка проверки соединения OAuth" + "oauthVerifyFailed": "Ошибка проверки соединения OAuth", + "configurationSaved": "Конфигурация сохранена", + "configurationUpdated": "Конфигурация обновлена", + "dataRefreshed": "Данные были обновлены", + "modelscope": { + "apiKey": "API -ключ", + "apiKeyHelper": "Получите ключ API в консоли моделей", + "apiKeyPlaceholder": "Пожалуйста, введите ключ API моделей моделей", + "baseUrl": "Адрес API", + "baseUrlHelper": "ModelsCope API -адрес службы службы", + "connected": "Подключенный", + "connecting": "Соединение ...", + "description": "ModelCope-это платформа для обмена моделями, запущенная Alibaba Damo Academy", + "details": { + "apiConfig": "Конфигурация API", + "mcpSync": "Синхронизация MCP", + "modelManagement": "Управление моделями", + "operationalDescription": "Синхронизировать серверы MCP, которые можно использовать непосредственно на платформе моделей", + "operationalServers": "Эксплуатация сервера", + "rateLimitConfig": "Конфигурация ограничения скорости", + "safetySettings": "Настройки безопасности", + "specialConfig": "Специальная конфигурация", + "syncFromModelScope": "Синхронизация от моделей", + "title": "Детали настроек поставщика" + }, + "invalidKey": "Неверный ключ API", + "keyRequired": "Пожалуйста, введите ключ API", + "mcpSync": { + "authenticationFailed": "Аутентификация не удалась, пожалуйста, проверьте ключ API", + "convertingServers": "Преобразование конфигурации сервера ...", + "description": "Синхронизация сервера MCP от моделей к локальным конфигурациям позволяет быстро добавлять обычно используемые инструменты MCP. Все службы отключены по умолчанию и могут быть включены вручную после импорта.", + "errorDetails": "Детали ошибки", + "errors": "Ошибка {count}", + "fetchingServers": "Получение списка серверов MCP ...", + "imported": "{count} Услуги были импортированы", + "importingServers": "Конфигурация импорта сервера ...", + "invalidServerData": "Неверные данные сервера", + "noApiKey": "Сначала настройте ключ API моделей ModelsCope", + "noOperationalUrls": "Не найдено доступного операционного адреса", + "noServersFound": "Не найдена доступной услуги MCP", + "pageNumber": "номер страницы", + "pageNumberPlaceholder": "Пожалуйста, введите номер страницы", + "pageSize": "Количество на страницу", + "serverAlreadyExists": "Сервер уже существует, пропустите импорт", + "skipped": "Skip {count} Сервисы", + "sync": "Начните синхронизировать", + "syncComplete": "Синхронное завершение", + "syncing": "Синхронизация ...", + "title": "Синхронизировать услуги MCP" + }, + "name": "Моделикоп", + "networkError": "Ошибка сетевого соединения", + "notConnected": "Не подключен", + "verifyFailed": "Проверка не удалась", + "verifySuccess": "Проверка успешна" + }, + "operationFailed": "Операция не удалась", + "operationSuccess": "Операция успешна", + "settingsApplied": "Применяются настройки" }, "knowledgeBase": { "title": "Настройки базы знаний", diff --git a/src/renderer/src/i18n/zh-CN/settings.json b/src/renderer/src/i18n/zh-CN/settings.json index 30e0b5783..95e9004fe 100644 --- a/src/renderer/src/i18n/zh-CN/settings.json +++ b/src/renderer/src/i18n/zh-CN/settings.json @@ -247,10 +247,68 @@ "stopModel": "停止模型", "pulling": "拉取中...", "runModel": "运行模型", + "configurationUpdated": "配置已更新", + "configurationSaved": "配置已保存", + "operationSuccess": "操作成功", + "operationFailed": "操作失败", + "dataRefreshed": "数据已刷新", + "settingsApplied": "设置已应用", "toast": { "modelRunning": "模型正在运行", "modelRunningDesc": "请先停止模型 {model},然后再删除。" }, + "modelscope": { + "name": "ModelScope", + "description": "ModelScope 是阿里巴巴达摩院推出的模型即服务共享平台", + "apiKey": "API 密钥", + "apiKeyPlaceholder": "请输入 ModelScope API Key", + "apiKeyHelper": "在 ModelScope 控制台获取您的 API Key", + "baseUrl": "API 地址", + "baseUrlHelper": "ModelScope API 服务地址", + "connected": "已连接", + "notConnected": "未连接", + "connecting": "连接中...", + "verifySuccess": "验证成功", + "verifyFailed": "验证失败", + "keyRequired": "请输入 API Key", + "invalidKey": "无效的 API Key", + "networkError": "网络连接错误", + "mcpSync": { + "title": "同步 MCP 服务", + "description": "从 ModelScope 同步 MCP 服务器到本地配置,可以快速添加常用的 MCP 工具。所有服务默认禁用,导入后可手动启用。", + "sync": "开始同步", + "syncing": "同步中...", + "pageSize": "每页数量", + "pageNumber": "页码", + "pageNumberPlaceholder": "请输入页码", + "imported": "已导入 {count} 个服务", + "skipped": "跳过 {count} 个服务", + "errors": "错误 {count} 个", + "errorDetails": "错误详情", + "noApiKey": "请先配置 ModelScope API Key", + "noServersFound": "未找到可用的 MCP 服务", + "fetchingServers": "正在获取 MCP 服务器列表...", + "convertingServers": "正在转换服务器配置...", + "importingServers": "正在导入服务器配置...", + "syncComplete": "同步完成", + "serverAlreadyExists": "服务器已存在,跳过导入", + "noOperationalUrls": "未找到可用的运营地址", + "invalidServerData": "无效的服务器数据", + "authenticationFailed": "认证失败,请检查 API Key" + }, + "details": { + "title": "提供商设置详情", + "apiConfig": "API 配置", + "rateLimitConfig": "速率限制配置", + "modelManagement": "模型管理", + "safetySettings": "安全设置", + "specialConfig": "特殊配置", + "mcpSync": "MCP 同步", + "operationalServers": "运营服务器", + "syncFromModelScope": "从 ModelScope 同步", + "operationalDescription": "同步 ModelScope 平台上可直接使用的 MCP 服务器" + } + }, "dialog": { "disableModel": { "title": "确认禁用模型", @@ -271,7 +329,10 @@ "failed": "验证失败", "success": "验证成功", "failedDesc": "API 密钥或配置验证失败,请检查配置信息", - "successDesc": "API 密钥和配置验证成功,可以正常使用" + "successDesc": "API 密钥和配置验证成功,可以正常使用", + "unauthorized": "认证失败,API Key 无效或已过期", + "serverError": "服务器错误,请稍后重试", + "connectionError": "连接错误,请检查网络连接和 API 地址" }, "addCustomProvider": { "title": "添加自定义服务商", diff --git a/src/renderer/src/i18n/zh-HK/settings.json b/src/renderer/src/i18n/zh-HK/settings.json index e73cc8fbb..5b21434b2 100644 --- a/src/renderer/src/i18n/zh-HK/settings.json +++ b/src/renderer/src/i18n/zh-HK/settings.json @@ -265,7 +265,10 @@ "failed": "驗證失敗", "success": "驗證成功", "failedDesc": "API 密鑰或配置驗證失敗,請檢查配置信息", - "successDesc": "API 密鑰和配置驗證成功,可以正常使用" + "successDesc": "API 密鑰和配置驗證成功,可以正常使用", + "connectionError": "連接錯誤,請檢查網絡連接和 API 地址", + "serverError": "服務器錯誤,請稍後重試", + "unauthorized": "認證失敗,API Key 無效或已過期" }, "addCustomProvider": { "title": "添加自定義服務商", @@ -374,7 +377,65 @@ "manageModels": "管理模型", "anthropicOAuthActiveTip": "OAuth 認證已啟用,您可以直接使用 Anthropic 服務", "oauthVerifySuccess": "OAuth 連接驗證成功", - "oauthVerifyFailed": "OAuth 連接驗證失敗" + "oauthVerifyFailed": "OAuth 連接驗證失敗", + "configurationSaved": "配置已保存", + "configurationUpdated": "配置已更新", + "dataRefreshed": "數據已刷新", + "modelscope": { + "apiKey": "API 密鑰", + "apiKeyHelper": "在 ModelScope 控制台獲取您的 API Key", + "apiKeyPlaceholder": "請輸入 ModelScope API Key", + "baseUrl": "API 地址", + "baseUrlHelper": "ModelScope API 服務地址", + "connected": "已連接", + "connecting": "連接中...", + "description": "ModelScope 是阿里巴巴達摩院推出的模型即服務共享平台", + "details": { + "apiConfig": "API 配置", + "mcpSync": "MCP 同步", + "modelManagement": "模型管理", + "operationalDescription": "同步 ModelScope 平台上可直接使用的 MCP 服務器", + "operationalServers": "運營服務器", + "rateLimitConfig": "速率限製配置", + "safetySettings": "安全設置", + "specialConfig": "特殊配置", + "syncFromModelScope": "從 ModelScope 同步", + "title": "提供商設置詳情" + }, + "invalidKey": "無效的 API Key", + "keyRequired": "請輸入 API Key", + "mcpSync": { + "authenticationFailed": "認證失敗,請檢查 API Key", + "convertingServers": "正在轉換服務器配置...", + "description": "從 ModelScope 同步 MCP 服務器到本地配置,可以快速添加常用的 MCP 工具。\n所有服務默認禁用,導入後可手動啟用。", + "errorDetails": "錯誤詳情", + "errors": "錯誤 {count} 個", + "fetchingServers": "正在獲取 MCP 服務器列表...", + "imported": "已導入 {count} 個服務", + "importingServers": "正在導入服務器配置...", + "invalidServerData": "無效的服務器數據", + "noApiKey": "請先配置 ModelScope API Key", + "noOperationalUrls": "未找到可用的運營地址", + "noServersFound": "未找到可用的 MCP 服務", + "pageNumber": "頁碼", + "pageNumberPlaceholder": "請輸入頁碼", + "pageSize": "每頁數量", + "serverAlreadyExists": "服務器已存在,跳過導入", + "skipped": "跳過 {count} 個服務", + "sync": "開始同步", + "syncComplete": "同步完成", + "syncing": "同步中...", + "title": "同步 MCP 服務" + }, + "name": "ModelScope", + "networkError": "網絡連接錯誤", + "notConnected": "未連接", + "verifyFailed": "驗證失敗", + "verifySuccess": "驗證成功" + }, + "operationFailed": "操作失敗", + "operationSuccess": "操作成功", + "settingsApplied": "設置已應用" }, "knowledgeBase": { "fastgptTitle": "FastGPT知識庫", diff --git a/src/renderer/src/i18n/zh-TW/settings.json b/src/renderer/src/i18n/zh-TW/settings.json index 728529296..421b7de4a 100644 --- a/src/renderer/src/i18n/zh-TW/settings.json +++ b/src/renderer/src/i18n/zh-TW/settings.json @@ -266,7 +266,10 @@ "failed": "驗證失敗", "success": "驗證成功", "failedDesc": "API 金鑰或設定驗證失敗,請檢查設定資訊", - "successDesc": "API 金鑰和設定驗證成功,可以正常使用" + "successDesc": "API 金鑰和設定驗證成功,可以正常使用", + "connectionError": "連接錯誤,請檢查網絡連接和 API 地址", + "serverError": "服務器錯誤,請稍後重試", + "unauthorized": "認證失敗,API Key 無效或已過期" }, "addCustomProvider": { "title": "新增自訂服務提供者", @@ -374,7 +377,65 @@ "manageModels": "管理模型", "anthropicOAuthActiveTip": "OAuth 認證已啟用,您可以直接使用 Anthropic 服務", "oauthVerifySuccess": "OAuth 連接驗證成功", - "oauthVerifyFailed": "OAuth 連接驗證失敗" + "oauthVerifyFailed": "OAuth 連接驗證失敗", + "modelscope": { + "mcpSync": { + "invalidServerData": "無效的服務器數據", + "authenticationFailed": "認證失敗,請檢查 API Key", + "convertingServers": "正在轉換服務器配置...", + "description": "從 ModelScope 同步 MCP 服務器到本地配置,可以快速添加常用的 MCP 工具。\n所有服務默認禁用,導入後可手動啟用。", + "errorDetails": "錯誤詳情", + "errors": "錯誤 {count} 個", + "fetchingServers": "正在獲取 MCP 服務器列表...", + "imported": "已導入 {count} 個服務", + "importingServers": "正在導入服務器配置...", + "noApiKey": "請先配置 ModelScope API Key", + "noOperationalUrls": "未找到可用的運營地址", + "noServersFound": "未找到可用的 MCP 服務", + "pageNumber": "頁碼", + "pageNumberPlaceholder": "請輸入頁碼", + "pageSize": "每頁數量", + "serverAlreadyExists": "服務器已存在,跳過導入", + "skipped": "跳過 {count} 個服務", + "sync": "開始同步", + "syncComplete": "同步完成", + "syncing": "同步中...", + "title": "同步 MCP 服務" + }, + "apiKey": "API 密鑰", + "apiKeyHelper": "在 ModelScope 控制台獲取您的 API Key", + "apiKeyPlaceholder": "請輸入 ModelScope API Key", + "baseUrl": "API 地址", + "baseUrlHelper": "ModelScope API 服務地址", + "connected": "已連接", + "connecting": "連接中...", + "description": "ModelScope 是阿里巴巴達摩院推出的模型即服務共享平台", + "details": { + "apiConfig": "API 配置", + "mcpSync": "MCP 同步", + "modelManagement": "模型管理", + "operationalDescription": "同步 ModelScope 平台上可直接使用的 MCP 服務器", + "operationalServers": "運營服務器", + "rateLimitConfig": "速率限製配置", + "safetySettings": "安全設置", + "specialConfig": "特殊配置", + "syncFromModelScope": "從 ModelScope 同步", + "title": "提供商設置詳情" + }, + "invalidKey": "無效的 API Key", + "keyRequired": "請輸入 API Key", + "name": "ModelScope", + "networkError": "網絡連接錯誤", + "notConnected": "未連接", + "verifyFailed": "驗證失敗", + "verifySuccess": "驗證成功" + }, + "configurationSaved": "配置已保存", + "configurationUpdated": "配置已更新", + "dataRefreshed": "數據已刷新", + "operationFailed": "操作失敗", + "operationSuccess": "操作成功", + "settingsApplied": "設置已應用" }, "knowledgeBase": { "title": "知識庫設置", diff --git a/src/shared/presenter.d.ts b/src/shared/presenter.d.ts index 777b6177a..b73a94f8d 100644 --- a/src/shared/presenter.d.ts +++ b/src/shared/presenter.d.ts @@ -528,6 +528,19 @@ export type LLM_EMBEDDING_ATTRS = { normalized: boolean } +// Simplified ModelScope MCP sync options +export interface ModelScopeMcpSyncOptions { + page_number?: number + page_size?: number +} + +// ModelScope MCP sync result interface +export interface ModelScopeMcpSyncResult { + imported: number + skipped: number + errors: string[] +} + export interface ILlmProviderPresenter { setProviders(provider: LLM_PROVIDER[]): void getProviders(): LLM_PROVIDER[] @@ -597,6 +610,10 @@ export interface ILlmProviderPresenter { lastRequestTime: number } > + syncModelScopeMcpServers( + providerId: string, + syncOptions?: ModelScopeMcpSyncOptions + ): Promise } export type CONVERSATION_SETTINGS = { systemPrompt: string