diff --git a/.env.example b/.env.example index b2a69da1d72..b5ca91edf7b 100644 --- a/.env.example +++ b/.env.example @@ -425,14 +425,14 @@ OPENAI_API_KEY=sk-xxxxxxxxx # MCP_TOOL_TIMEOUT=60000 # ####################################### -# ######### Klavis Service ############## +# ######### Composio Service ############ # ####################################### -# Klavis API Key for accessing Strata hosted MCP servers -# Get your API key from: https://klavis.io +# Composio API Key for accessing hosted integrations (Gmail, Slack, etc.) +# Get your API key from: https://composio.dev # IMPORTANT: This key is stored server-side only and NEVER exposed to the client -# When this key is set, Klavis integration will be automatically enabled -# KLAVIS_API_KEY=your_klavis_api_key_here +# When this key is set, Composio integration will be automatically enabled +# COMPOSIO_API_KEY=your_composio_api_key_here # ####################################### # #### Message Gateway (IM Integration) ## diff --git a/apps/server/src/globalConfig/getServerGlobalConfig.test.ts b/apps/server/src/globalConfig/getServerGlobalConfig.test.ts index dcb28c8465e..306709b0d28 100644 --- a/apps/server/src/globalConfig/getServerGlobalConfig.test.ts +++ b/apps/server/src/globalConfig/getServerGlobalConfig.test.ts @@ -28,8 +28,8 @@ const mockGlobalConfigDependencies = ( ENABLE_BUSINESS_FEATURES: enableBusinessFeatures, })); - vi.doMock('@/config/klavis', () => ({ - klavisEnv: {}, + vi.doMock('@/config/composio', () => ({ + composioEnv: {}, })); vi.doMock('@/const/version', () => ({ diff --git a/apps/server/src/globalConfig/index.ts b/apps/server/src/globalConfig/index.ts index 34b71a83d18..856bf3104b1 100644 --- a/apps/server/src/globalConfig/index.ts +++ b/apps/server/src/globalConfig/index.ts @@ -1,7 +1,7 @@ import { ENABLE_BUSINESS_FEATURES } from '@lobechat/business-const'; import { ModelProvider } from 'model-bank'; -import { klavisEnv } from '@/config/klavis'; +import { composioEnv } from '@/config/composio'; import { isDesktop } from '@/const/version'; import { appEnv, getAppConfig } from '@/envs/app'; import { authEnv } from '@/envs/auth'; @@ -104,9 +104,9 @@ export const getServerGlobalConfig = async () => { disableEmailPassword: authEnv.AUTH_DISABLE_EMAIL_PASSWORD, enableBusinessFeatures: ENABLE_BUSINESS_FEATURES, enableEmailVerification: authEnv.AUTH_EMAIL_VERIFICATION, + enableComposio: !!composioEnv.COMPOSIO_API_KEY, enableGatewayMode: ENABLE_BUSINESS_FEATURES || (!!appEnv.ENABLE_AGENT_GATEWAY && !!appEnv.AGENT_GATEWAY_URL), - enableKlavis: !!klavisEnv.KLAVIS_API_KEY, enableLobehubSkill: !!(appEnv.MARKET_TRUSTED_CLIENT_SECRET && appEnv.MARKET_TRUSTED_CLIENT_ID), enableMagicLink: authEnv.AUTH_ENABLE_MAGIC_LINK, enableMarketTrustedClient: !!( diff --git a/apps/server/src/modules/AgentRuntime/RuntimeExecutors.ts b/apps/server/src/modules/AgentRuntime/RuntimeExecutors.ts index 95551df219c..ceba50e52ed 100644 --- a/apps/server/src/modules/AgentRuntime/RuntimeExecutors.ts +++ b/apps/server/src/modules/AgentRuntime/RuntimeExecutors.ts @@ -14,14 +14,14 @@ import { } from '@lobechat/agent-runtime'; import { LobeActivatorIdentifier } from '@lobechat/builtin-tool-activator'; import { + type ComposioServiceSummary, type CredSummary, + generateComposioServicesList, generateCredsList, - generateKlavisServicesList, - type KlavisServiceSummary, } from '@lobechat/builtin-tool-creds'; import { LocalSystemManifest } from '@lobechat/builtin-tool-local-system'; import { BRANDING_PROVIDER } from '@lobechat/business-const'; -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { type AgentContextDocument, type AgentGroupConfig, @@ -68,7 +68,7 @@ import { import { sanitizeToolCallArguments, serializePartsForStorage } from '@lobechat/utils'; import debug from 'debug'; -import { klavisEnv } from '@/config/klavis'; +import { composioEnv } from '@/config/composio'; import { type MessageModel, MessageModel as MessageModelClass } from '@/database/models/message'; import { TopicModel } from '@/database/models/topic'; import { UserModel } from '@/database/models/user'; @@ -999,39 +999,38 @@ export const createRuntimeExecutors = ( } } - // {{KLAVIS_SERVICES_LIST}} — used by lobe-creds system role (Klavis integrations section). - // Mirrors client-side: klavisStoreSelectors.getServers() filtered by connection status. - let klavisServicesListStr = ''; - if (ctx.serverDB && ctx.userId && !!klavisEnv.KLAVIS_API_KEY) { + // {{COMPOSIO_SERVICES_LIST}} — used by lobe-creds system role (Composio integrations section). + let composioServicesListStr = ''; + if (ctx.serverDB && ctx.userId && !!composioEnv.COMPOSIO_API_KEY) { try { const { PluginModel } = await import('@/database/models/plugin'); const pluginModel = new PluginModel(ctx.serverDB, ctx.userId, ctx.workspaceId); const allPlugins = await pluginModel.query(); - const validKlavisIds = new Set(KLAVIS_SERVER_TYPES.map((t) => t.identifier)); + const validComposioIds = new Set(COMPOSIO_APP_TYPES.map((t) => t.identifier)); const connectedIds = new Set( allPlugins .filter( (p) => - validKlavisIds.has(p.identifier) && - (p.customParams as any)?.klavis?.isAuthenticated === true, + validComposioIds.has(p.identifier) && + (p.customParams as any)?.composio?.status === 'ACTIVE', ) .map((p) => p.identifier), ); - const connected: KlavisServiceSummary[] = KLAVIS_SERVER_TYPES.filter((t) => + const connected: ComposioServiceSummary[] = COMPOSIO_APP_TYPES.filter((t) => connectedIds.has(t.identifier), ).map((t) => ({ identifier: t.identifier, name: t.label })); - const available: KlavisServiceSummary[] = KLAVIS_SERVER_TYPES.filter( + const available: ComposioServiceSummary[] = COMPOSIO_APP_TYPES.filter( (t) => !connectedIds.has(t.identifier), ).map((t) => ({ identifier: t.identifier, name: t.label })); - klavisServicesListStr = generateKlavisServicesList(connected, available); + composioServicesListStr = generateComposioServicesList(connected, available); log( - 'Fetched Klavis services for {{KLAVIS_SERVICES_LIST}}: connected=%d, available=%d', + 'Fetched Composio services for {{COMPOSIO_SERVICES_LIST}}: connected=%d, available=%d', connected.length, available.length, ); } catch (error) { log( - 'Failed to fetch Klavis services for {{KLAVIS_SERVICES_LIST}} substitution: %O', + 'Failed to fetch Composio services for {{COMPOSIO_SERVICES_LIST}} substitution: %O', error, ); } @@ -1055,7 +1054,7 @@ export const createRuntimeExecutors = ( sandbox_enabled: sandboxEnabled, sandbox_uploaded_files: sandboxUploadedFiles, CREDS_LIST: credsListStr, - KLAVIS_SERVICES_LIST: klavisServicesListStr, + COMPOSIO_SERVICES_LIST: composioServicesListStr, // Memory tool variables memory_effort: memoryEffort, }, @@ -2446,7 +2445,7 @@ export const createRuntimeExecutors = ( execution = { attempts: 1, result: dispatchResult }; } else { // Inject source from sourceMap so BuiltinToolsExecutor can route - // lobehubSkill / klavis tools correctly (LLM responses don't carry source) + // lobehubSkill / composio tools correctly (LLM responses don't carry source) if (toolSource && !chatToolPayload.source) { chatToolPayload.source = toolSource; } @@ -3026,7 +3025,7 @@ export const createRuntimeExecutors = ( execution = { attempts: 1, result: dispatchResult }; } else { // Inject source from sourceMap so BuiltinToolsExecutor can route - // lobehubSkill / klavis tools correctly (LLM responses don't carry source) + // lobehubSkill / composio tools correctly (LLM responses don't carry source) const batchToolSource = state.operationToolSet?.sourceMap?.[chatToolPayload.identifier] ?? state.toolSourceMap?.[chatToolPayload.identifier]; diff --git a/apps/server/src/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts b/apps/server/src/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts index 3361417e78a..4c90933a2ac 100644 --- a/apps/server/src/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts +++ b/apps/server/src/modules/AgentRuntime/__tests__/RuntimeExecutors.test.ts @@ -76,11 +76,11 @@ vi.mock('model-bank', () => ({ LOBE_DEFAULT_MODEL_LIST: mockBuiltinModels, })); -// klavisEnv uses @t3-oss/env-nextjs which throws in jsdom (treats it as client context) -vi.mock('@/config/klavis', () => ({ - getKlavisConfig: vi.fn(), - getServerKlavisApiKey: vi.fn().mockReturnValue(undefined), - klavisEnv: { KLAVIS_API_KEY: undefined }, +// composioEnv uses @t3-oss/env-nextjs which throws in jsdom (treats it as client context) +vi.mock('@/config/composio', () => ({ + getComposioConfig: vi.fn(), + getServerComposioApiKey: vi.fn().mockReturnValue(undefined), + composioEnv: { COMPOSIO_API_KEY: undefined }, })); // fileEnv uses @t3-oss/env-core; stub the only field the runtime reads so the diff --git a/apps/server/src/modules/Mecha/AgentToolsEngine/index.ts b/apps/server/src/modules/Mecha/AgentToolsEngine/index.ts index 3ee3a440c1e..0706258f74e 100644 --- a/apps/server/src/modules/Mecha/AgentToolsEngine/index.ts +++ b/apps/server/src/modules/Mecha/AgentToolsEngine/index.ts @@ -86,7 +86,7 @@ export const createServerToolsEngine = ( // Combine all manifests, then drop anything whose identifier the caller // has explicitly forbidden for this turn. The post-merge filter closes // the second half of the wall: an installed plugin or a - // Skill/Klavis manifest claiming `lobe-remote-device` would otherwise + // Skill/Composio manifest claiming `lobe-remote-device` would otherwise // slip through `buildAllowedBuiltinTools` (which only touches the // builtin source). const combinedManifests = [...pluginManifests, ...builtinManifests, ...additionalManifests]; @@ -256,7 +256,7 @@ export const createServerAgentToolsEngine = ( : isChatMode ? chatModeAllowedToolIds : defaultToolIds, - // Post-merge wall: a plugin or Skill/Klavis manifest claiming a + // Post-merge wall: a plugin or Skill/Composio manifest claiming a // device identifier survives `buildAllowedBuiltinTools` (which only // filters the builtin source). Excluding the identifiers here drops // them from the combined `manifestSchemas` so the activator cannot diff --git a/apps/server/src/modules/Mecha/AgentToolsEngine/types.ts b/apps/server/src/modules/Mecha/AgentToolsEngine/types.ts index df0be11ad24..b3226150cad 100644 --- a/apps/server/src/modules/Mecha/AgentToolsEngine/types.ts +++ b/apps/server/src/modules/Mecha/AgentToolsEngine/types.ts @@ -22,7 +22,7 @@ export interface ServerAgentToolsContext { * Configuration options for createServerToolsEngine */ export interface ServerAgentToolsEngineConfig { - /** Additional manifests to include (e.g., Klavis tools) */ + /** Additional manifests to include (e.g., Composio tools) */ additionalManifests?: LobeToolManifest[]; /** * Override the list of builtin tools fed into the engine's @@ -39,7 +39,7 @@ export interface ServerAgentToolsEngineConfig { /** * Identifiers to drop from `manifestSchemas` after combining plugin, * builtin, and additional manifests. Filtering builtins alone is not - * enough: an installed plugin or a Skill/Klavis manifest can declare + * enough: an installed plugin or a Skill/Composio manifest can declare * `identifier: 'lobe-remote-device'` and slip past `buildAllowedBuiltinTools`. * This is the final post-merge wall referenced in . */ diff --git a/apps/server/src/routers/lambda/composio.ts b/apps/server/src/routers/lambda/composio.ts new file mode 100644 index 00000000000..42c9d4d51c0 --- /dev/null +++ b/apps/server/src/routers/lambda/composio.ts @@ -0,0 +1,256 @@ +import { type ToolManifest } from '@lobechat/types'; +import { TRPCError } from '@trpc/server'; +import { z } from 'zod'; + +import { getServerComposioAuthConfigId } from '@/config/composio'; +import { PluginModel } from '@/database/models/plugin'; +import { getComposioClient } from '@/libs/composio'; +import { authedProcedure, router } from '@/libs/trpc/lambda'; +import { serverDatabase } from '@/libs/trpc/lambda/middleware'; + +const composioProcedure = authedProcedure.use(serverDatabase).use(async (opts) => { + const client = getComposioClient(); + const pluginModel = new PluginModel(opts.ctx.serverDB, opts.ctx.userId); + + return opts.next({ + ctx: { ...opts.ctx, composioClient: client, pluginModel }, + }); +}); + +export const composioRouter = router({ + createConnection: composioProcedure + .input( + z.object({ + appSlug: z.string(), + identifier: z.string(), + label: z.string(), + }), + ) + .mutation(async ({ input, ctx }) => { + const { appSlug, identifier, label } = input; + const { userId } = ctx; + + const callbackUrl = `${process.env.APP_URL || process.env.NEXTAUTH_URL || ''}/api/composio/oauth/callback`; + + // Prefer a pre-configured auth config (e.g. a custom/white-label config + // created in the Composio dashboard), pinned per toolkit via env. Falls + // back to discovering an existing config for this toolkit, and finally to + // auto-creating a Composio-managed one. + let authConfigId = getServerComposioAuthConfigId(identifier); + if (!authConfigId) { + const authConfigs = await (ctx.composioClient.authConfigs as any).list(); + let authConfig = authConfigs?.items?.find( + (c: any) => c.toolkit?.slug?.toLowerCase() === appSlug.toLowerCase(), + ); + if (!authConfig) { + authConfig = await (ctx.composioClient.authConfigs as any).create(appSlug, { + name: appSlug, + type: 'use_composio_managed_auth', + }); + } + authConfigId = authConfig.id; + } + + if (!authConfigId) { + throw new TRPCError({ + code: 'INTERNAL_SERVER_ERROR', + message: `Failed to resolve a Composio auth config for "${appSlug}".`, + }); + } + + // Composio-managed OAuth auth configs no longer support `initiate`; use + // `link` (POST /api/v3/connected_accounts/link) to get the redirect URL. + const connReq = await (ctx.composioClient.connectedAccounts as any).link( + userId, + authConfigId, + { callbackUrl }, + ); + + let rawTools: any[] = []; + try { + const toolsResp = await (ctx.composioClient.tools as any).getRawComposioTools({ + toolkits: [appSlug], + }); + rawTools = toolsResp?.items || toolsResp || []; + } catch { + // tools may not be available before auth + } + + const manifest: ToolManifest = { + api: Array.isArray(rawTools) + ? rawTools.map((tool: any) => ({ + description: tool.description || '', + name: tool.slug || tool.name || '', + parameters: tool.inputParameters || + tool.inputSchema || { + properties: {}, + type: 'object', + }, + })) + : [], + identifier, + meta: { + avatar: '🔌', + description: `Composio: ${label}`, + title: label, + }, + type: 'default', + }; + + await ctx.pluginModel.create({ + customParams: { + composio: { + appSlug, + authConfigId, + connectedAccountId: connReq.id, + redirectUrl: connReq.redirectUrl, + status: 'PENDING', + }, + }, + identifier, + manifest, + source: 'composio', + type: 'plugin', + }); + + return { + authConfigId, + connectedAccountId: connReq.id, + identifier, + redirectUrl: connReq.redirectUrl, + }; + }), + + deleteConnection: composioProcedure + .input( + z.object({ + connectedAccountId: z.string(), + identifier: z.string(), + }), + ) + .mutation(async ({ input, ctx }) => { + try { + await (ctx.composioClient.connectedAccounts as any).delete(input.connectedAccountId); + } catch (error) { + console.warn('[Composio] Failed to delete remote connection:', error); + } + + await ctx.pluginModel.delete(input.identifier); + + return { success: true }; + }), + + getComposioPlugins: composioProcedure.query(async ({ ctx }) => { + const allPlugins = await ctx.pluginModel.query(); + return allPlugins.filter((plugin) => plugin.customParams?.composio); + }), + + getConnection: composioProcedure + .input( + z.object({ + connectedAccountId: z.string(), + }), + ) + .query(async ({ input, ctx }) => { + try { + const account = await (ctx.composioClient.connectedAccounts as any).get( + input.connectedAccountId, + ); + return { + appSlug: account?.toolkit?.slug || '', + connectedAccountId: input.connectedAccountId, + error: undefined as 'AUTH_ERROR' | undefined, + status: (account?.status || 'PENDING') as string, + }; + } catch (error) { + const errorMessage = error instanceof Error ? error.message : String(error); + const isAuthError = errorMessage.includes('401') || errorMessage.includes('Unauthorized'); + + if (isAuthError) { + return { + appSlug: '', + connectedAccountId: input.connectedAccountId, + error: 'AUTH_ERROR' as const, + status: 'FAILED', + }; + } + throw error; + } + }), + + removeComposioPlugin: composioProcedure + .input(z.object({ identifier: z.string() })) + .mutation(async ({ input, ctx }) => { + await ctx.pluginModel.delete(input.identifier); + return { success: true }; + }), + + updateComposioPlugin: composioProcedure + .input( + z.object({ + appSlug: z.string(), + authConfigId: z.string(), + connectedAccountId: z.string(), + identifier: z.string(), + label: z.string(), + redirectUrl: z.string().optional(), + status: z.string(), + tools: z.array( + z.object({ + description: z.string().optional(), + inputSchema: z.any().optional(), + name: z.string(), + }), + ), + }), + ) + .mutation(async ({ input, ctx }) => { + const { + identifier, + label, + appSlug, + authConfigId, + connectedAccountId, + tools, + status, + redirectUrl, + } = input; + + const existingPlugin = await ctx.pluginModel.findById(identifier); + + const manifest: ToolManifest = { + api: tools.map((tool) => ({ + description: tool.description || '', + name: tool.name, + parameters: tool.inputSchema || { properties: {}, type: 'object' }, + })), + identifier, + meta: existingPlugin?.manifest?.meta || { + avatar: '🔌', + description: `Composio: ${label}`, + title: label, + }, + type: 'default', + }; + + const customParams = { + composio: { appSlug, authConfigId, connectedAccountId, redirectUrl, status }, + }; + + if (existingPlugin) { + await ctx.pluginModel.update(identifier, { customParams, manifest }); + } else { + await ctx.pluginModel.create({ + customParams, + identifier, + manifest, + source: 'composio', + type: 'plugin', + }); + } + + return { savedCount: tools.length }; + }), +}); + +export type ComposioRouter = typeof composioRouter; diff --git a/apps/server/src/routers/lambda/connector.ts b/apps/server/src/routers/lambda/connector.ts index 2def5ab040c..43e44197a0d 100644 --- a/apps/server/src/routers/lambda/connector.ts +++ b/apps/server/src/routers/lambda/connector.ts @@ -363,7 +363,7 @@ export const connectorRouter = router({ }), /** - * Sync tools from a client-provided list (for Lobehub OAuth skills, Klavis, etc. + * Sync tools from a client-provided list (for Lobehub OAuth skills, Composio, etc. * that already have their tool list available on the client side). * Idempotent — safe to call whenever the detail panel opens. */ diff --git a/apps/server/src/routers/lambda/index.ts b/apps/server/src/routers/lambda/index.ts index 894ee1aec23..146bec470ec 100644 --- a/apps/server/src/routers/lambda/index.ts +++ b/apps/server/src/routers/lambda/index.ts @@ -37,6 +37,7 @@ import { briefRouter } from './brief'; import { changelogRouter } from './changelog'; import { chunkRouter } from './chunk'; import { comfyuiRouter } from './comfyui'; +import { composioRouter } from './composio'; import { configRouter } from './config'; import { connectorRouter } from './connector'; import { deviceRouter } from './device'; @@ -50,7 +51,6 @@ import { generationTopicRouter } from './generationTopic'; import { homeRouter } from './home'; import { imageRouter } from './image'; import { importerRouter } from './importer'; -import { klavisRouter } from './klavis'; import { knowledgeRouter } from './knowledge'; import { knowledgeBaseRouter } from './knowledgeBase'; import { llmGenerationTracingRouter } from './llmGenerationTracing'; @@ -115,7 +115,8 @@ export const lambdaRouter = router({ home: homeRouter, image: imageRouter, importer: importerRouter, - klavis: klavisRouter, + composio: composioRouter, + knowledge: knowledgeRouter, knowledgeBase: knowledgeBaseRouter, llmGenerationTracing: llmGenerationTracingRouter, diff --git a/apps/server/src/routers/lambda/klavis.ts b/apps/server/src/routers/lambda/klavis.ts deleted file mode 100644 index 5b3cd6efe12..00000000000 --- a/apps/server/src/routers/lambda/klavis.ts +++ /dev/null @@ -1,284 +0,0 @@ -import { type ToolManifest } from '@lobechat/types'; -import { z } from 'zod'; - -import { withScopedPermission } from '@/business/server/trpc-middlewares/rbacPermission'; -import { wsCompatProcedure } from '@/business/server/trpc-middlewares/workspaceAuth'; -import { PluginModel } from '@/database/models/plugin'; -import { getKlavisClient } from '@/libs/klavis'; -import { router } from '@/libs/trpc/lambda'; -import { serverDatabase } from '@/libs/trpc/lambda/middleware'; - -/** - * Klavis procedure with API key validation and database access - */ -const klavisProcedure = wsCompatProcedure.use(serverDatabase).use(async (opts) => { - const client = getKlavisClient(); - const wsId = opts.ctx.workspaceId ?? undefined; - const pluginModel = new PluginModel(opts.ctx.serverDB, opts.ctx.userId, wsId); - - return opts.next({ - ctx: { ...opts.ctx, klavisClient: client, pluginModel }, - }); -}); - -export const klavisRouter = router({ - /** - * Create a single MCP server instance and save to database - * Returns: { serverUrl, instanceId, oauthUrl?, identifier, serverName } - */ - createServerInstance: klavisProcedure - .use(withScopedPermission('agent:update')) - .input( - z.object({ - /** Identifier for storage (e.g., 'google-calendar') */ - identifier: z.string(), - /** Server name for Klavis API (e.g., 'Google Calendar') */ - serverName: z.string(), - userId: z.string(), - }), - ) - .mutation(async ({ input, ctx }) => { - const { serverName, userId, identifier } = input; - - // Create a single server instance - const response = await ctx.klavisClient.mcpServer.createServerInstance({ - serverName: serverName as any, - userId, - }); - - const { serverUrl, instanceId, oauthUrl } = response; - - // Get the tool list for this server - const toolsResponse = await ctx.klavisClient.mcpServer.getTools(serverName as any); - const tools = toolsResponse.tools || []; - - // Save to database using the provided identifier (format: lowercase, spaces replaced with hyphens) - const manifest: ToolManifest = { - api: tools.map((tool: any) => ({ - description: tool.description || '', - name: tool.name, - parameters: tool.inputSchema || { properties: {}, type: 'object' }, - })), - identifier, - meta: { - avatar: '🔌', - description: `LobeHub Mcp Server: ${serverName}`, - title: serverName, - }, - type: 'default', - }; - - // Save to database with oauthUrl and isAuthenticated status - const isAuthenticated = !oauthUrl; // If there's no oauthUrl, authentication is not required or already authenticated - await ctx.pluginModel.create({ - customParams: { - klavis: { - instanceId, - isAuthenticated, - oauthUrl, - serverName, - serverUrl, - }, - }, - identifier, - manifest, - source: 'klavis', - type: 'plugin', - }); - - return { - identifier, - instanceId, - isAuthenticated, - oauthUrl, - serverName, - serverUrl, - }; - }), - - /** - * Delete a server instance - */ - deleteServerInstance: klavisProcedure - .use(withScopedPermission('agent:update')) - .input( - z.object({ - /** Identifier for storage (e.g., 'google-calendar') */ - identifier: z.string(), - instanceId: z.string(), - }), - ) - .mutation(async ({ input, ctx }) => { - // Call Klavis API to delete server instance - await ctx.klavisClient.mcpServer.deleteServerInstance(input.instanceId); - - // Delete from database (using identifier) - await ctx.pluginModel.delete(input.identifier); - - return { success: true }; - }), - - /** - * Get Klavis plugins from database - */ - getKlavisPlugins: klavisProcedure.query(async ({ ctx }) => { - const allPlugins = await ctx.pluginModel.query(); - // Filter plugins that have klavis customParams - return allPlugins.filter((plugin) => plugin.customParams?.klavis); - }), - - /** - * Get server instance status from Klavis API - * Returns error object instead of throwing on auth errors (useful for polling) - */ - getServerInstance: klavisProcedure - .input( - z.object({ - instanceId: z.string(), - }), - ) - .query(async ({ input, ctx }) => { - try { - const response = await ctx.klavisClient.mcpServer.getServerInstance(input.instanceId); - return { - authNeeded: response.authNeeded, - error: undefined, - externalUserId: response.externalUserId, - instanceId: response.instanceId, - isAuthenticated: response.isAuthenticated, - oauthUrl: response.oauthUrl, - platform: response.platform, - serverName: response.serverName, - }; - } catch (error) { - // Check if this is an authentication error - const errorMessage = error instanceof Error ? error.message : String(error); - const isAuthError = - errorMessage.includes('Invalid API key or instance ID') || - errorMessage.includes('Status code: 401'); - - // For auth errors, return error object instead of throwing - // This prevents 500 errors in logs during polling - if (isAuthError) { - return { - authNeeded: true, - error: 'AUTH_ERROR', - externalUserId: undefined, - instanceId: input.instanceId, - isAuthenticated: false, - oauthUrl: undefined, - platform: undefined, - serverName: undefined, - }; - } - - // For other errors, still throw - throw error; - } - }), - - getUserIntergrations: klavisProcedure - .input( - z.object({ - userId: z.string(), - }), - ) - .query(async ({ input, ctx }) => { - const response = await ctx.klavisClient.user.getUserIntegrations(input.userId); - - return { - integrations: response.integrations, - }; - }), - - /** - * Remove Klavis plugin from database by identifier - */ - removeKlavisPlugin: klavisProcedure - .use(withScopedPermission('agent:update')) - .input( - z.object({ - /** Identifier for storage (e.g., 'google-calendar') */ - identifier: z.string(), - }), - ) - .mutation(async ({ input, ctx }) => { - await ctx.pluginModel.delete(input.identifier); - return { success: true }; - }), - - /** - * Update Klavis plugin with tools and auth status in database - */ - updateKlavisPlugin: klavisProcedure - .use(withScopedPermission('agent:update')) - .input( - z.object({ - /** Identifier for storage (e.g., 'google-calendar') */ - identifier: z.string(), - instanceId: z.string(), - isAuthenticated: z.boolean(), - oauthUrl: z.string().optional(), - /** Server name for Klavis API (e.g., 'Google Calendar') */ - serverName: z.string(), - serverUrl: z.string(), - tools: z.array( - z.object({ - description: z.string().optional(), - inputSchema: z.any().optional(), - name: z.string(), - }), - ), - }), - ) - .mutation(async ({ input, ctx }) => { - const { identifier, serverName, serverUrl, instanceId, tools, isAuthenticated, oauthUrl } = - input; - - // Get existing plugin (using identifier) - const existingPlugin = await ctx.pluginModel.findById(identifier); - - // Build manifest containing all tools - const manifest: ToolManifest = { - api: tools.map((tool) => ({ - description: tool.description || '', - name: tool.name, - parameters: tool.inputSchema || { properties: {}, type: 'object' }, - })), - identifier, - meta: existingPlugin?.manifest?.meta || { - avatar: '🔌', - description: `LobeHub Mcp Server: ${serverName}`, - title: serverName, - }, - type: 'default', - }; - - const customParams = { - klavis: { - instanceId, - isAuthenticated, - oauthUrl, - serverName, - serverUrl, - }, - }; - - // Update or create plugin - if (existingPlugin) { - await ctx.pluginModel.update(identifier, { customParams, manifest }); - } else { - await ctx.pluginModel.create({ - customParams, - identifier, - manifest, - source: 'klavis', - type: 'plugin', - }); - } - - return { savedCount: tools.length }; - }), -}); - -export type KlavisRouter = typeof klavisRouter; diff --git a/apps/server/src/routers/lambda/oauthDeviceFlow.ts b/apps/server/src/routers/lambda/oauthDeviceFlow.ts index 5876ac3eddb..d52acaf20d6 100644 --- a/apps/server/src/routers/lambda/oauthDeviceFlow.ts +++ b/apps/server/src/routers/lambda/oauthDeviceFlow.ts @@ -53,7 +53,7 @@ export const oauthDeviceFlowRouter = router({ ); if (!providerDetail?.keyVaults) { - return { isAuthenticated: false }; + return { status: 'PENDING' }; } const keyVaults = providerDetail.keyVaults as Record; @@ -63,12 +63,12 @@ export const oauthDeviceFlowRouter = router({ return { avatarUrl: keyVaults.githubAvatarUrl as string | undefined, expiresAt: keyVaults.oauthTokenExpiresAt || keyVaults.bearerTokenExpiresAt, - isAuthenticated: true, + status: 'ACTIVE', username: keyVaults.githubUsername as string | undefined, }; } - return { isAuthenticated: false }; + return { status: 'PENDING' }; }), /** diff --git a/apps/server/src/routers/tools/composio.ts b/apps/server/src/routers/tools/composio.ts new file mode 100644 index 00000000000..a82631cc458 --- /dev/null +++ b/apps/server/src/routers/tools/composio.ts @@ -0,0 +1,115 @@ +import { TRPCError } from '@trpc/server'; +import { z } from 'zod'; + +import { PluginModel } from '@/database/models/plugin'; +import { getComposioClient } from '@/libs/composio'; +import { authedProcedure, publicProcedure, router } from '@/libs/trpc/lambda'; +import { serverDatabase } from '@/libs/trpc/lambda/middleware'; +import { MCPService } from '@/server/services/mcp'; + +const composioProcedure = authedProcedure.use(serverDatabase).use(async (opts) => { + const composioClient = getComposioClient(); + const pluginModel = new PluginModel(opts.ctx.serverDB, opts.ctx.userId); + return opts.next({ ctx: { ...opts.ctx, composioClient, pluginModel } }); +}); + +export const composioToolsRouter = router({ + executeAction: composioProcedure + .input( + z.object({ + identifier: z.string(), + toolArgs: z.record(z.unknown()).optional(), + toolSlug: z.string(), + }), + ) + .mutation(async ({ ctx, input }) => { + // Resolve the connected account server-side from the caller's own plugin + // record (PluginModel is user-scoped). Never trust a connectedAccountId + // supplied by the client — that would let a user drive another user's + // connection. + const plugin = await ctx.pluginModel.findById(input.identifier); + const connectedAccountId = plugin?.customParams?.composio?.connectedAccountId; + + if (!connectedAccountId) { + throw new TRPCError({ + code: 'NOT_FOUND', + message: `No Composio connection found for "${input.identifier}".`, + }); + } + + const result = await (ctx.composioClient.tools as any).execute(input.toolSlug, { + arguments: input.toolArgs || {}, + connectedAccountId, + // Toolkit version resolves to "latest"; allow manual execution without a + // pinned version (Composio otherwise throws ComposioToolVersionRequiredError). + dangerouslySkipVersionCheck: true, + userId: ctx.userId, + }); + + if (!result) { + return { + content: 'Unknown error', + state: { content: [{ text: 'Unknown error', type: 'text' }], isError: true }, + success: false, + }; + } + + const data = result as any; + const content = data?.data || data?.result || data; + const contentStr = typeof content === 'string' ? content : JSON.stringify(content); + + return await MCPService.processToolCallResult({ + content: [{ text: contentStr, type: 'text' }], + isError: false, + }); + }), + + getActions: publicProcedure.input(z.object({ appSlug: z.string() })).query(async ({ input }) => { + const client = getComposioClient(); + const response = await (client.tools as any).getRawComposioTools({ + toolkits: [input.appSlug], + }); + + const items = response?.items || response || []; + const tools = Array.isArray(items) + ? items.map((tool: any) => ({ + description: tool.description || '', + inputSchema: tool.inputParameters || + tool.inputSchema || { + properties: {}, + type: 'object', + }, + name: tool.slug || tool.name || '', + })) + : []; + + return { tools }; + }), + + listActions: composioProcedure + .input(z.object({ appSlug: z.string() })) + .query(async ({ ctx, input }) => { + // Use getRawComposioTools (raw tool defs with slug/inputParameters), NOT + // tools.get() — the latter returns provider-wrapped (OpenAI-format) tools + // whose name/params live under `.function`, so slug/name/inputSchema come + // back empty and every tool collapses to the same `${identifier}____` name. + const response = await (ctx.composioClient.tools as any).getRawComposioTools({ + toolkits: [input.appSlug], + }); + + const items = response?.items || response || []; + const tools = Array.isArray(items) + ? items.map((tool: any) => ({ + description: tool.description || '', + inputSchema: tool.inputParameters || + tool.inputSchema || { + properties: {}, + type: 'object', + }, + name: tool.slug || tool.name || '', + })) + : []; + + return { tools }; + }), +}); diff --git a/apps/server/src/routers/tools/index.ts b/apps/server/src/routers/tools/index.ts index 846a7d54be2..35df087123a 100644 --- a/apps/server/src/routers/tools/index.ts +++ b/apps/server/src/routers/tools/index.ts @@ -1,13 +1,14 @@ import { publicProcedure, router } from '@/libs/trpc/lambda'; -import { klavisRouter } from './klavis'; +import { composioToolsRouter } from './composio'; import { marketRouter } from './market'; import { mcpRouter } from './mcp'; import { searchRouter } from './search'; export const toolsRouter = router({ healthcheck: publicProcedure.query(() => "i'm live!"), - klavis: klavisRouter, + composio: composioToolsRouter, + market: marketRouter, mcp: mcpRouter, search: searchRouter, diff --git a/apps/server/src/routers/tools/klavis.ts b/apps/server/src/routers/tools/klavis.ts deleted file mode 100644 index 0d389700bea..00000000000 --- a/apps/server/src/routers/tools/klavis.ts +++ /dev/null @@ -1,141 +0,0 @@ -import { z } from 'zod'; - -import { wsCompatProcedure } from '@/business/server/trpc-middlewares/workspaceAuth'; -import { ConnectorModel } from '@/database/models/connector'; -import { ConnectorToolModel } from '@/database/models/connectorTool'; -import { ConnectorToolPermission } from '@/database/schemas'; -import { getKlavisClient } from '@/libs/klavis'; -import { publicProcedure, router } from '@/libs/trpc/lambda'; -import { serverDatabase } from '@/libs/trpc/lambda/middleware'; -import { MCPService } from '@/server/services/mcp'; - -/** - * Klavis procedure with client initialized in context - */ -const klavisProcedure = wsCompatProcedure.use(serverDatabase).use(async (opts) => { - const klavisClient = getKlavisClient(); - - return opts.next({ - ctx: { ...opts.ctx, klavisClient }, - }); -}); - -/** - * Klavis router for tools - * Contains callTool and listTools which call external Klavis API - */ -export const klavisRouter = router({ - /** - * Call a tool on a Klavis Strata server - */ - callTool: klavisProcedure - .input( - z.object({ - /** Klavis server identifier (e.g. 'gmail', 'google-calendar') for precise permission lookup */ - identifier: z.string().optional(), - serverUrl: z.string(), - toolArgs: z.record(z.unknown()).optional(), - toolName: z.string(), - }), - ) - .mutation(async ({ ctx, input }) => { - // ── Connector tool permission gate ──────────────────────────────────── - // Use identifier + toolName when available for a precise lookup (avoids - // same-name collisions across connectors). Falls back to toolName-only - // if identifier is absent (legacy callers). - if (ctx.userId && ctx.serverDB) { - const wsId = ctx.workspaceId ?? undefined; - const connectorToolModel = new ConnectorToolModel(ctx.serverDB, ctx.userId, wsId); - let connectorTool: - | Awaited> - | undefined; - - if (input.identifier) { - const connectorModel = new ConnectorModel(ctx.serverDB, ctx.userId, wsId); - const [connector] = await connectorModel.queryByIdentifiers([input.identifier]); - if (connector) { - const tools = await connectorToolModel.queryByConnector(connector.id); - connectorTool = tools.find((t) => t.toolName === input.toolName); - } - } else { - connectorTool = await connectorToolModel.findByToolName(input.toolName); - } - - if (connectorTool?.permission === ConnectorToolPermission.disabled) { - const message = - `The tool "${input.toolName}" has been disabled by the user and cannot be executed. ` + - `Please inform the user that this tool is currently disabled. ` + - `They can re-enable it in Settings > Connectors.`; - return { - content: message, - state: { content: [{ text: message, type: 'text' }], isError: false }, - success: true, - }; - } - } - // ── End permission gate ─────────────────────────────────────────────── - - const response = await ctx.klavisClient.mcpServer.callTools({ - serverUrl: input.serverUrl, - toolArgs: input.toolArgs, - toolName: input.toolName, - }); - - // Handle error case - if (!response.success || !response.result) { - return { - content: response.error || 'Unknown error', - state: { - content: [{ text: response.error || 'Unknown error', type: 'text' }], - isError: true, - }, - success: false, - }; - } - - // Process the response using the common MCP tool call result processor - const processedResult = await MCPService.processToolCallResult({ - content: (response.result.content || []) as any[], - isError: response.result.isError, - }); - - return processedResult; - }), - - /** - * Get tools by server name (public endpoint, no auth required) - */ - getTools: publicProcedure - .input( - z.object({ - serverName: z.string(), - }), - ) - .query(async ({ input }) => { - const klavisClient = getKlavisClient(); - const response = await klavisClient.mcpServer.getTools(input.serverName as any); - - return { - tools: response.tools, - }; - }), - - /** - * List tools available on a Klavis Strata server - */ - listTools: klavisProcedure - .input( - z.object({ - serverUrl: z.string(), - }), - ) - .query(async ({ ctx, input }) => { - const response = await ctx.klavisClient.mcpServer.listTools({ - serverUrl: input.serverUrl, - }); - - return { - tools: response.tools, - }; - }), -}); diff --git a/apps/server/src/services/agentRuntime/AgentRuntimeService.test.ts b/apps/server/src/services/agentRuntime/AgentRuntimeService.test.ts index 63a0599f40c..e8edfc01f71 100644 --- a/apps/server/src/services/agentRuntime/AgentRuntimeService.test.ts +++ b/apps/server/src/services/agentRuntime/AgentRuntimeService.test.ts @@ -1696,7 +1696,7 @@ describe('AgentRuntimeService', () => { expect(casSpy).not.toHaveBeenCalled(); }); - it('arms a one-shot verify when the parent has not parked yet and scheduleVerifyOnHold is set', async () => { + it('arms the first verify (attempt 1, 15s) when the parent has not parked yet and scheduleVerifyOnHold is set', async () => { // Child completed before the parent's parking step persisted its state. mockCoordinator.loadAgentState.mockResolvedValue({ pendingToolsCalling: [], @@ -1712,14 +1712,15 @@ describe('AgentRuntimeService', () => { expect(won).toBe(false); expect(mockQueueService.scheduleMessage).toHaveBeenCalledWith( expect.objectContaining({ + delay: 15_000, operationId: parentOpId, - payload: { verifyAsyncToolBarrier: true }, + payload: { asyncToolVerifyAttempt: 1, verifyAsyncToolBarrier: true }, stepIndex: 2, }), ); }); - it('arms a one-shot verify when the barrier is unsatisfied and scheduleVerifyOnHold is set', async () => { + it('arms a verify when the barrier is unsatisfied and scheduleVerifyOnHold is set', async () => { mockCoordinator.loadAgentState.mockResolvedValue({ pendingToolsCalling: [{ id: 'tc1' }], status: 'waiting_for_async_tool', @@ -1736,7 +1737,104 @@ describe('AgentRuntimeService', () => { expect(won).toBe(false); expect(mockQueueService.scheduleMessage).toHaveBeenCalledWith( - expect.objectContaining({ payload: { verifyAsyncToolBarrier: true } }), + expect.objectContaining({ + payload: { asyncToolVerifyAttempt: 1, verifyAsyncToolBarrier: true }, + }), + ); + }); + + it('re-arms the next verify with exponential backoff while the barrier holds', async () => { + mockCoordinator.loadAgentState.mockResolvedValue({ + pendingToolsCalling: [{ id: 'tc1' }], + status: 'waiting_for_async_tool', + stepCount: 1, + }); + (service as any).serverDB.query = { + messagePlugins: { findFirst: vi.fn().mockResolvedValue(null) }, + }; + + // A verify handler running as attempt 2 re-arms attempt 3 (60s). + await service.tryResumeParentFromAsyncTool( + { parentOperationId: parentOpId }, + { scheduleVerifyOnHold: true, verifyAttempt: 3 }, + ); + + expect(mockQueueService.scheduleMessage).toHaveBeenCalledWith( + expect.objectContaining({ + delay: 60_000, + payload: { asyncToolVerifyAttempt: 3, verifyAsyncToolBarrier: true }, + }), + ); + }); + + it('stops re-arming once the bounded attempts are exhausted', async () => { + mockCoordinator.loadAgentState.mockResolvedValue({ + pendingToolsCalling: [{ id: 'tc1' }], + status: 'waiting_for_async_tool', + stepCount: 1, + }); + (service as any).serverDB.query = { + messagePlugins: { findFirst: vi.fn().mockResolvedValue(null) }, + }; + + const won = await service.tryResumeParentFromAsyncTool( + { parentOperationId: parentOpId }, + { scheduleVerifyOnHold: true, verifyAttempt: 6 }, + ); + + expect(won).toBe(false); + expect(mockQueueService.scheduleMessage).not.toHaveBeenCalled(); + }); + + it('trusts a just-backfilled message id without re-reading it (read-your-writes)', async () => { + mockCoordinator.loadAgentState.mockResolvedValue({ + pendingToolsCalling: [{ id: 'tc1' }], + status: 'waiting_for_async_tool', + stepCount: 3, + }); + // Plugin row exists (created at park) but its state still reads stale. + const findById = vi.fn().mockResolvedValue({ content: '' }); + (service as any).serverDB.query = { + messagePlugins: { + findFirst: vi.fn().mockResolvedValue({ id: 'msg-tc1', state: null, toolCallId: 'tc1' }), + }, + }; + (service as any).messageModel.findById = findById; + const casSpy = vi + .spyOn(AgentOperationModel.prototype, 'tryResumeFromAsyncTool') + .mockResolvedValue(true); + + const won = await service.tryResumeParentFromAsyncTool( + { parentOperationId: parentOpId }, + { knownFulfilledMessageId: 'msg-tc1' }, + ); + + expect(won).toBe(true); + expect(casSpy).toHaveBeenCalledWith(parentOpId); + // The stale read must be skipped — barrier trusted the local backfill. + expect(findById).not.toHaveBeenCalled(); + }); + + it('arms a fallback verify when a parked op has no pending tools', async () => { + mockCoordinator.loadAgentState.mockResolvedValue({ + pendingToolsCalling: [], + status: 'waiting_for_async_tool', + stepCount: 4, + }); + const casSpy = vi.spyOn(AgentOperationModel.prototype, 'tryResumeFromAsyncTool'); + + const won = await service.tryResumeParentFromAsyncTool( + { parentOperationId: parentOpId }, + { scheduleVerifyOnHold: true }, + ); + + expect(won).toBe(false); + expect(casSpy).not.toHaveBeenCalled(); + expect(mockQueueService.scheduleMessage).toHaveBeenCalledWith( + expect.objectContaining({ + payload: { asyncToolVerifyAttempt: 1, verifyAsyncToolBarrier: true }, + stepIndex: 4, + }), ); }); @@ -1805,7 +1903,7 @@ describe('AgentRuntimeService', () => { }); expect(resumeSpy).toHaveBeenCalledWith( { parentOperationId: 'parent-op-1' }, - { scheduleVerifyOnHold: true }, + { knownFulfilledMessageId: 'tool-msg-1', scheduleVerifyOnHold: true }, ); }); diff --git a/apps/server/src/services/agentRuntime/AgentRuntimeService.ts b/apps/server/src/services/agentRuntime/AgentRuntimeService.ts index f9e69a52705..1062be444f3 100644 --- a/apps/server/src/services/agentRuntime/AgentRuntimeService.ts +++ b/apps/server/src/services/agentRuntime/AgentRuntimeService.ts @@ -20,6 +20,7 @@ import { trace as otelTrace, } from '@lobechat/observability-otel/api'; import { + asyncToolResumeCounter, buildInvokeAgentAttributes, buildInvokeAgentResultAttributes, invokeAgentSpanName, @@ -84,13 +85,37 @@ if (process.env.VERCEL) { const log = debug('lobe-server:agent-runtime-service'); /** - * Delay before a one-shot `verifyAsyncToolBarrier` re-check fires after a + * Base delay before the first `verifyAsyncToolBarrier` re-check fires after a * sub-agent completion found the parent not yet resumable. Long enough for * the parent's parking step to finish persisting, short enough that a lost - * resume is recovered promptly. + * resume is recovered promptly. Subsequent attempts back off exponentially — + * see {@link asyncToolVerifyDelayMs}. */ const ASYNC_TOOL_VERIFY_DELAY_MS = 15_000; +/** + * Maximum number of bounded watchdog re-checks armed per parked parent. The + * watchdog re-arms after each unsatisfied check (instead of the old single + * shot) so a transient miss — a read-replica lag, a sibling dying between + * backfill and resume — is retried rather than leaving the parent stuck in + * `waiting_for_async_tool` forever. With exponential backoff from a 15s base, + * 5 attempts span ~15s → ~7.75min total before giving up. See LOBE-10385. + */ +const ASYNC_TOOL_VERIFY_MAX_ATTEMPTS = 5; + +/** Hard ceiling on a single backoff delay so late attempts don't overshoot. */ +const ASYNC_TOOL_VERIFY_MAX_DELAY_MS = 240_000; + +/** + * Exponential backoff delay for the Nth (1-based) watchdog re-check: + * 15s, 30s, 60s, 120s, 240s, capped at {@link ASYNC_TOOL_VERIFY_MAX_DELAY_MS}. + */ +const asyncToolVerifyDelayMs = (attempt: number): number => + Math.min( + ASYNC_TOOL_VERIFY_DELAY_MS * 2 ** (Math.max(1, attempt) - 1), + ASYNC_TOOL_VERIFY_MAX_DELAY_MS, + ); + /** * Format error for storage in message pluginError metadata. * Handles Error objects which don't serialize properly with JSON.stringify. @@ -590,15 +615,28 @@ export class AgentRuntimeService { resumeAsyncTool, toolMessageId, verifyAsyncToolBarrier, + asyncToolVerifyAttempt, externalRetryCount = 0, } = params; // Watchdog re-check for a parked async-tool wait: re-run the barrier + CAS // without claiming the step lock or executing anything. Idempotent — the // CAS guarantees at most one real resume regardless of how many checks run. + // Opt back into `scheduleVerifyOnHold` with the next attempt so an + // unsatisfied barrier re-arms (bounded backoff) instead of giving up after + // a single shot — the core LOBE-10385 fix. if (verifyAsyncToolBarrier) { - log('[%s][%d] Running async-tool barrier verify', operationId, stepIndex); - const resumed = await this.tryResumeParentFromAsyncTool({ parentOperationId: operationId }); + const attempt = asyncToolVerifyAttempt ?? 1; + log( + '[%s][%d] Running async-tool barrier verify (attempt %d)', + operationId, + stepIndex, + attempt, + ); + const resumed = await this.tryResumeParentFromAsyncTool( + { parentOperationId: operationId }, + { scheduleVerifyOnHold: true, verifyAttempt: attempt + 1 }, + ); return { nextStepScheduled: resumed, state: {}, @@ -1627,12 +1665,30 @@ export class AgentRuntimeService { */ async tryResumeParentFromAsyncTool( params: { parentOperationId: string }, - options?: { scheduleVerifyOnHold?: boolean }, + options?: { + /** + * Message id of a tool placeholder the caller just backfilled to a + * terminal state. Trusted by the barrier as fulfilled without re-reading + * `message_plugins` — closes the read-your-writes gap where the barrier + * query hits a read replica that hasn't seen the just-committed write. + */ + knownFulfilledMessageId?: string; + scheduleVerifyOnHold?: boolean; + /** 1-based watchdog attempt to arm when the parent isn't resumable yet. */ + verifyAttempt?: number; + }, ): Promise { const { parentOperationId } = params; const state = await this.coordinator.loadAgentState(parentOperationId); - if (!state) return false; + if (!state) { + // State expired (Redis TTL) or never persisted — nothing left to resume. + // Surface it: a missing state at completion time is how a parent silently + // strands. There is no stepCount/status to arm a verify against. + log('[%s] async-tool resume: parent state missing/expired, cannot resume', parentOperationId); + asyncToolResumeCounter.add(1, { outcome: 'no_state' }); + return false; + } if (state.status !== 'waiting_for_async_tool') { // Not parked (yet). Either the op already resumed/finished — nothing to @@ -1643,12 +1699,27 @@ export class AgentRuntimeService { } const pending = (state.pendingToolsCalling ?? []) as ChatToolPayload[]; - if (pending.length === 0) return false; + if (pending.length === 0) { + // Parked but no pending tools recorded — usually the parked snapshot's + // `pendingToolsCalling` hasn't finished persisting yet. Warn, report, and + // arm a fallback re-check rather than returning silently (the old bug). + log( + '[%s] async-tool resume: parked op has no pending tools, arming fallback', + parentOperationId, + ); + asyncToolResumeCounter.add(1, { outcome: 'no_pending' }); + await this.maybeScheduleAsyncToolVerify(parentOperationId, state, options); + return false; + } // Barrier: every pending tool must have a fulfilled tool_result message. - const allFulfilled = await this.allPendingToolsFulfilled(pending); + const allFulfilled = await this.allPendingToolsFulfilled( + pending, + options?.knownFulfilledMessageId, + ); if (!allFulfilled) { log('[%s] async-tool barrier not yet satisfied, holding', parentOperationId); + asyncToolResumeCounter.add(1, { outcome: 'barrier_held' }); await this.maybeScheduleAsyncToolVerify(parentOperationId, state, options); return false; } @@ -1659,9 +1730,12 @@ export class AgentRuntimeService { ); if (!won) { log('[%s] lost async-tool resume CAS, no-op', parentOperationId); + asyncToolResumeCounter.add(1, { outcome: 'lost_cas' }); return false; } + asyncToolResumeCounter.add(1, { outcome: 'resumed' }); + log('[%s] won async-tool resume CAS, scheduling step %d', parentOperationId, state.stepCount); if (this.queueService) { @@ -1682,36 +1756,60 @@ export class AgentRuntimeService { } /** - * Arm a one-shot delayed `verifyAsyncToolBarrier` re-check for a parent op - * whose resume attempt found it not yet resumable. Skipped for terminal - * states (nothing left to resume) and when the caller didn't opt in — the - * verify execution itself never re-arms, keeping retries bounded to one - * per completion event. + * Arm the next bounded `verifyAsyncToolBarrier` re-check for a parent op whose + * resume attempt found it not yet resumable. Skipped for terminal states + * (nothing left to resume) and when the caller didn't opt in. + * + * Unlike the original single shot, the watchdog re-arms after each unsatisfied + * check: the verify handler re-enters here with `verifyAttempt + 1`, backing + * off exponentially up to {@link ASYNC_TOOL_VERIFY_MAX_ATTEMPTS}. A transient + * miss (read-replica lag, a sibling dying between backfill and resume) is thus + * retried instead of permanently stranding the parent. Once attempts are + * exhausted the chain stops and the `verify_exhausted` metric fires so the + * orphan is observable. See LOBE-10385. */ private async maybeScheduleAsyncToolVerify( parentOperationId: string, state: AgentState, - options?: { scheduleVerifyOnHold?: boolean }, + options?: { scheduleVerifyOnHold?: boolean; verifyAttempt?: number }, ): Promise { if (!options?.scheduleVerifyOnHold || !this.queueService) return; const status = state.status as string; if (status === 'done' || status === 'error' || status === 'interrupted') return; + const attempt = options.verifyAttempt ?? 1; + if (attempt > ASYNC_TOOL_VERIFY_MAX_ATTEMPTS) { + // Bounded retries spent and the parent is still not resumable — give up + // re-arming and report so the stuck wait can be detected, not silently + // accumulated. + log( + '[%s] async-tool barrier verify exhausted after %d attempts, giving up (status: %s)', + parentOperationId, + ASYNC_TOOL_VERIFY_MAX_ATTEMPTS, + status, + ); + asyncToolResumeCounter.add(1, { outcome: 'verify_exhausted' }); + return; + } + + const delay = asyncToolVerifyDelayMs(attempt); log( - '[%s] scheduling async-tool barrier verify in %dms (status: %s)', + '[%s] scheduling async-tool barrier verify attempt %d/%d in %dms (status: %s)', parentOperationId, - ASYNC_TOOL_VERIFY_DELAY_MS, + attempt, + ASYNC_TOOL_VERIFY_MAX_ATTEMPTS, + delay, status, ); try { await this.queueService.scheduleMessage({ context: undefined, - delay: ASYNC_TOOL_VERIFY_DELAY_MS, + delay, endpoint: `${this.baseURL}/run`, operationId: parentOperationId, - payload: { verifyAsyncToolBarrier: true }, + payload: { asyncToolVerifyAttempt: attempt, verifyAsyncToolBarrier: true }, priority: 'high', stepIndex: state.stepCount, }); @@ -1792,22 +1890,40 @@ export class AgentRuntimeService { ); } - // 2. Barrier + CAS + resume the parent op (infra errors propagate too) - return this.tryResumeParentFromAsyncTool({ parentOperationId }, { scheduleVerifyOnHold: true }); + // 2. Barrier + CAS + resume the parent op (infra errors propagate too). + // Pass the just-backfilled message id so the barrier trusts this write + // instead of re-reading a possibly-stale replica. + return this.tryResumeParentFromAsyncTool( + { parentOperationId }, + { knownFulfilledMessageId: toolMessageId, scheduleVerifyOnHold: true }, + ); } /** * Whether every pending tool call has a fulfilled tool_result message — i.e. * a tool message exists for its `tool_call_id` with non-empty content or a * terminal pluginState. Looks up by `tool_call_id` (plugin id === message id). + * + * `knownFulfilledMessageId` short-circuits the per-tool content/state read for + * a placeholder the caller just backfilled in the same request: its terminal + * write is a local fact, so re-reading it (possibly from a lagging read + * replica) would only risk a false negative that strands the parent. The + * plugin row itself predates the park, so the `tool_call_id → plugin.id` + * lookup still resolves; only the freshly written content/state is trusted. */ - private async allPendingToolsFulfilled(pending: ChatToolPayload[]): Promise { + private async allPendingToolsFulfilled( + pending: ChatToolPayload[], + knownFulfilledMessageId?: string, + ): Promise { for (const tc of pending) { const plugin = await this.serverDB.query.messagePlugins.findFirst({ where: (mp, { eq }) => eq(mp.toolCallId, tc.id), }); if (!plugin) return false; + // Trust the caller's own just-committed backfill (read-your-writes). + if (knownFulfilledMessageId && plugin.id === knownFulfilledMessageId) continue; + const message = await this.messageModel.findById(plugin.id); const pluginState = plugin.state as { status?: string } | null; const fulfilled = diff --git a/apps/server/src/services/agentRuntime/types.ts b/apps/server/src/services/agentRuntime/types.ts index f962ad32a4f..a8e0ca5a469 100644 --- a/apps/server/src/services/agentRuntime/types.ts +++ b/apps/server/src/services/agentRuntime/types.ts @@ -121,6 +121,12 @@ export type StepCompletionReason = export interface AgentExecutionParams { approvedToolCall?: any; + /** + * 1-based attempt number carried by a `verifyAsyncToolBarrier` re-check so the + * bounded watchdog can back off and stop after a fixed number of tries. Absent + * (treated as attempt 1) on the first re-check armed by a completion bridge. + */ + asyncToolVerifyAttempt?: number; context?: AgentRuntimeContext; externalRetryCount?: number; humanInput?: any; @@ -144,10 +150,13 @@ export interface AgentExecutionParams { /** * Watchdog re-check for a parked `waiting_for_async_tool` op: re-runs the * resume barrier + CAS without claiming the step lock or executing a step. - * A no-op when the op already resumed or the barrier is still unsatisfied. - * Scheduled one-shot by `tryResumeParentFromAsyncTool` when a sub-agent - * completion found the parent not yet resumable (covers the - * child-finishes-before-parent-parks race and transient barrier failures). + * A no-op when the op already resumed. While the barrier is still unsatisfied + * it re-arms the next check with exponential backoff (see + * `asyncToolVerifyAttempt`) up to a bounded number of attempts, so a transient + * miss is retried rather than permanently stranding the parent. First armed by + * `tryResumeParentFromAsyncTool` when a sub-agent completion found the parent + * not yet resumable (covers the child-finishes-before-parent-parks race and + * transient barrier failures). */ verifyAsyncToolBarrier?: boolean; } @@ -221,6 +230,9 @@ export interface OperationCreationParams { deviceAccessPolicy?: { canUseDevice: boolean; reason: DeviceAccessReason }; /** Device system info for placeholder variable replacement in Local System systemRole */ deviceSystemInfo?: Record; + /** Discord context for injecting channel/guild info into agent system message */ + discordContext?: any; + evalContext?: any; /** * Resolved execution plan for the run (see `resolveExecutionPlan`). * Forwarded into `state.metadata.executionPlan` so step-level layers (the @@ -228,9 +240,6 @@ export interface OperationCreationParams { * device capability from raw config. */ executionPlan?: ExecutionPlan; - /** Discord context for injecting channel/guild info into agent system message */ - discordContext?: any; - evalContext?: any; /** * External lifecycle hooks * Registered once, auto-adapt to local (in-memory) or production (webhook) mode diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.builtinRuntime.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.builtinRuntime.test.ts index 2127d24c480..f2a8a0b65d8 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.builtinRuntime.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.builtinRuntime.test.ts @@ -141,9 +141,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.connectorOverlap.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.connectorOverlap.test.ts index 503aa5b30cf..57a22fd072f 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.connectorOverlap.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.connectorOverlap.test.ts @@ -97,9 +97,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.device.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.device.test.ts index 373bb8df5ee..e58ca104fa4 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.device.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.device.test.ts @@ -101,9 +101,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.deviceToolPipeline.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.deviceToolPipeline.test.ts index 865ada5bd12..add5933cbc7 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.deviceToolPipeline.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.deviceToolPipeline.test.ts @@ -98,9 +98,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.disableTools.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.disableTools.test.ts index 57eacb9c778..d7a65ef54cc 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.disableTools.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.disableTools.test.ts @@ -7,7 +7,7 @@ const { mockCreateOperation, mockCreateServerAgentToolsEngine, mockGetAgentConfig, - mockGetKlavisManifests, + mockGetComposioManifests, mockGetLobehubSkillManifests, mockMessageCreate, mockPluginQuery, @@ -18,7 +18,7 @@ const { getEnabledPluginManifests: vi.fn().mockReturnValue(new Map()), }), mockGetAgentConfig: vi.fn(), - mockGetKlavisManifests: vi.fn().mockResolvedValue([]), + mockGetComposioManifests: vi.fn().mockResolvedValue([]), mockGetLobehubSkillManifests: vi.fn().mockResolvedValue([]), mockMessageCreate: vi.fn(), mockPluginQuery: vi.fn().mockResolvedValue([]), @@ -97,9 +97,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: mockGetKlavisManifests, +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: mockGetComposioManifests, })), })); @@ -176,7 +176,7 @@ describe('AiAgentService.execAgent - disableTools', () => { // Manifest fetches should NOT be called expect(mockGetLobehubSkillManifests).not.toHaveBeenCalled(); - expect(mockGetKlavisManifests).not.toHaveBeenCalled(); + expect(mockGetComposioManifests).not.toHaveBeenCalled(); // ToolsEngine should NOT be created expect(mockCreateServerAgentToolsEngine).not.toHaveBeenCalled(); @@ -196,7 +196,7 @@ describe('AiAgentService.execAgent - disableTools', () => { // All tool discovery steps should be called expect(mockPluginQuery).toHaveBeenCalledTimes(1); expect(mockGetLobehubSkillManifests).toHaveBeenCalledTimes(1); - expect(mockGetKlavisManifests).toHaveBeenCalledTimes(1); + expect(mockGetComposioManifests).toHaveBeenCalledTimes(1); expect(mockCreateServerAgentToolsEngine).toHaveBeenCalledTimes(1); }); }); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.files.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.files.test.ts index df4f0cbd24b..81db5c5f99c 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.files.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.files.test.ts @@ -100,9 +100,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.headlessDefault.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.headlessDefault.test.ts index 213c53145f2..cb0cce0076c 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.headlessDefault.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.headlessDefault.test.ts @@ -68,9 +68,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.modelOverride.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.modelOverride.test.ts index c0a8cefbf61..8e7e1b4408f 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.modelOverride.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.modelOverride.test.ts @@ -68,9 +68,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.resume.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.resume.test.ts index 20b90af64b4..495697abe61 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.resume.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.resume.test.ts @@ -91,9 +91,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.resumeApproval.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.resumeApproval.test.ts index 8341dd56866..698d4eb6e10 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.resumeApproval.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.resumeApproval.test.ts @@ -101,9 +101,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.threadId.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.threadId.test.ts index 6cb9826c917..eb557a9dec2 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.threadId.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.threadId.test.ts @@ -100,10 +100,10 @@ vi.mock('@/server/services/market', () => ({ })), })); -// Mock KlavisService (for getKlavisManifests) -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +// Mock ComposioService (for getComposioManifests) +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execAgent.topicHistory.test.ts b/apps/server/src/services/aiAgent/__tests__/execAgent.topicHistory.test.ts index cb7ece40c18..a868a076b3e 100644 --- a/apps/server/src/services/aiAgent/__tests__/execAgent.topicHistory.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execAgent.topicHistory.test.ts @@ -90,9 +90,9 @@ vi.mock('@/server/services/market', () => ({ })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/__tests__/execSubAgent.test.ts b/apps/server/src/services/aiAgent/__tests__/execSubAgent.test.ts index 44ef1e7d0bf..8c480e81a6c 100644 --- a/apps/server/src/services/aiAgent/__tests__/execSubAgent.test.ts +++ b/apps/server/src/services/aiAgent/__tests__/execSubAgent.test.ts @@ -87,10 +87,10 @@ vi.mock('@/server/services/market', () => ({ })), })); -// Mock KlavisService -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({ - getKlavisManifests: vi.fn().mockResolvedValue([]), +// Mock ComposioService +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({ + getComposioManifests: vi.fn().mockResolvedValue([]), })), })); diff --git a/apps/server/src/services/aiAgent/index.ts b/apps/server/src/services/aiAgent/index.ts index 2ebbdac0128..4715f932527 100644 --- a/apps/server/src/services/aiAgent/index.ts +++ b/apps/server/src/services/aiAgent/index.ts @@ -95,6 +95,7 @@ import { resolveAgentSelfIterationCapability, } from '@/server/services/agentSignal/featureGate'; import { shouldSuppressSignal } from '@/server/services/agentSignal/suppressSignal'; +import { ComposioService } from '@/server/services/composio'; import { deviceGateway } from '@/server/services/deviceGateway'; import { DocumentService } from '@/server/services/document'; import { FileService } from '@/server/services/file'; @@ -104,7 +105,6 @@ import { } from '@/server/services/file/resolveAttachments'; import { HeterogeneousAgentService } from '@/server/services/heterogeneousAgent'; import type { ConversationHistoryEntry } from '@/server/services/heterogeneousAgent/cloudHeteroContext'; -import { KlavisService } from '@/server/services/klavis'; import { MarketService } from '@/server/services/market'; import { markdownToTxt } from '@/utils/markdownToTxt'; @@ -287,7 +287,7 @@ export class AiAgentService { private readonly topicModel: TopicModel; private readonly agentRuntimeService: AgentRuntimeService; private readonly marketService: MarketService; - private readonly klavisService: KlavisService; + private readonly composioService: ComposioService; private readonly workspaceId?: string; @@ -327,7 +327,7 @@ export class AiAgentService { workspaceId: wsId, }); this.marketService = new MarketService({ userInfo: { userId } }); - this.klavisService = new KlavisService({ db, userId, workspaceId: wsId }); + this.composioService = new ComposioService({ db, userId }); } private async resolveOperationTaskId( @@ -1393,7 +1393,7 @@ export class AiAgentService { // These are needed outside the tools block (for agent management context, skill engine, etc.) let lobehubSkillManifests: LobeToolManifest[] = []; - let klavisManifests: LobeToolManifest[] = []; + let composioManifests: LobeToolManifest[] = []; let connectorManifests: ReturnType = []; let agentPlugins: string[] = [...(agentConfig?.plugins ?? []), ...(additionalPluginIds || [])]; @@ -1458,7 +1458,7 @@ export class AiAgentService { : []; // Only connectors WITH a real MCP endpoint (mcpServerUrl or stdio) can replace plugins in the - // manifest. Connectors WITHOUT an endpoint (e.g. Lobehub/Klavis OAuth skills synced via + // manifest. Connectors WITHOUT an endpoint (e.g. Lobehub/Composio OAuth skills synced via // syncToolsFromClient) must continue using their original plugin executor path — otherwise // after humanIntervention approval the runtime tries to call mcpServerUrl='' and returns empty. const connectorsMcp = connectors.filter( @@ -1503,24 +1503,24 @@ export class AiAgentService { } log('execAgent: got %d lobehub skill manifests', lobehubSkillManifests.length); - // 5d. Fetch Klavis tool manifests from database + // 5d. Fetch Composio tool manifests from database try { - klavisManifests = await this.klavisService.getKlavisManifests(); + composioManifests = await this.composioService.getComposioManifests(); } catch (error) { - log('execAgent: failed to fetch klavis manifests: %O', error); + log('execAgent: failed to fetch composio manifests: %O', error); } - log('execAgent: got %d klavis manifests', klavisManifests.length); + log('execAgent: got %d composio manifests', composioManifests.length); - // 5d-1. Patch Lobehub/Klavis manifests AND community-MCP plugin manifests + // 5d-1. Patch Lobehub/Composio manifests AND community-MCP plugin manifests // with connector tool permissions. This enables needs_approval (→ // humanIntervention: 'required') and disabled (→ blocking description) for // any tool managed via the connector system but executed through a - // non-connector path (Lobehub/Klavis skills, community MCP plugins). + // non-connector path (Lobehub/Composio skills, community MCP plugins). // The 'disabled' hard-block is already enforced universally in // ToolExecutionService; this surfaces the permission to the model too. if ( lobehubSkillManifests.length > 0 || - klavisManifests.length > 0 || + composioManifests.length > 0 || pluginsWithoutConnectors.length > 0 ) { try { @@ -1529,7 +1529,7 @@ export class AiAgentService { const { ConnectorToolModel } = await import('@/database/models/connectorTool'); const allIdentifiers = [ ...lobehubSkillManifests.map((m) => m.identifier), - ...klavisManifests.map((m) => m.identifier), + ...composioManifests.map((m) => m.identifier), ...pluginsWithoutConnectors.map((p) => p.identifier), ]; const connectorEntries = @@ -1555,7 +1555,7 @@ export class AiAgentService { : m; }); - klavisManifests = klavisManifests.map((m) => { + composioManifests = composioManifests.map((m) => { const perms = connectorToolsMap.get(m.identifier); return perms && perms.size > 0 ? (patchManifestWithPermissions(m as any, perms as any) as any) @@ -1687,7 +1687,7 @@ export class AiAgentService { ); const toolsEngine = createServerAgentToolsEngine(toolsContext, { - additionalManifests: [...lobehubSkillManifests, ...klavisManifests, ...connectorManifests], + additionalManifests: [...lobehubSkillManifests, ...composioManifests, ...connectorManifests], agentConfig: { chatConfig: agentConfig.chatConfig ?? undefined, plugins: agentPlugins, @@ -1717,9 +1717,9 @@ export class AiAgentService { ...agentPlugins, ...(disableLocalSystem ? [] : [LocalSystemManifest.identifier]), RemoteDeviceManifest.identifier, - // Include LobeHub Skills and Klavis tools so they are passed to generateToolsDetailed + // Include LobeHub Skills and Composio tools so they are passed to generateToolsDetailed ...lobehubSkillManifests.map((m) => m.identifier), - ...klavisManifests.map((m) => m.identifier), + ...composioManifests.map((m) => m.identifier), // Connector manifests are also injected as additionalManifests ...connectorManifests.map((m) => m.identifier), ]), @@ -1740,7 +1740,7 @@ export class AiAgentService { // Single guard for every `toolManifestMap[id] = ...` ingest below. // Mirrors the post-merge filter in `createServerToolsEngine`: an - // installed plugin, a LobeHub Skill, or a Klavis manifest declaring + // installed plugin, a LobeHub Skill, or a Composio manifest declaring // `identifier: 'lobe-remote-device'` would otherwise reach the // activator-discovery map and let an external bot sender enable it // (). Centralising the check at the ingest layer means @@ -1814,14 +1814,14 @@ export class AiAgentService { toolManifestMap[LocalSystemManifest.identifier] = LocalSystemManifest as LobeToolManifest; } - // Include lobehub skill and klavis manifests for activator discovery + // Include lobehub skill and composio manifests for activator discovery for (const manifest of lobehubSkillManifests) { if (!isManifestIngestAllowed(manifest.identifier)) continue; if (!toolManifestMap[manifest.identifier]) { toolManifestMap[manifest.identifier] = manifest; } } - for (const manifest of klavisManifests) { + for (const manifest of composioManifests) { if (!isManifestIngestAllowed(manifest.identifier)) continue; if (!toolManifestMap[manifest.identifier]) { toolManifestMap[manifest.identifier] = manifest; @@ -1832,9 +1832,9 @@ export class AiAgentService { if (!isManifestIngestAllowed(manifest.identifier)) continue; toolSourceMap[manifest.identifier] = 'lobehubSkill'; } - for (const manifest of klavisManifests) { + for (const manifest of composioManifests) { if (!isManifestIngestAllowed(manifest.identifier)) continue; - toolSourceMap[manifest.identifier] = 'klavis'; + toolSourceMap[manifest.identifier] = 'composio'; } // Mark tools that must run on the user's machine (local-system, stdio @@ -1866,10 +1866,10 @@ export class AiAgentService { } log( - 'execAgent: generated %d tools, %d lobehub skills, %d klavis tools', + 'execAgent: generated %d tools, %d lobehub skills, %d composio tools', tools?.length ?? 0, lobehubSkillManifests.length, - klavisManifests.length, + composioManifests.length, ); const agentSelfIterationEnabled = agentConfig.chatConfig?.selfIteration?.enabled === true; @@ -2095,12 +2095,12 @@ export class AiAgentService { name: manifest.meta?.title || manifest.identifier, type: 'lobehub-skill' as const, })), - // Klavis tools - ...klavisManifests.map((manifest) => ({ + // Composio tools + ...composioManifests.map((manifest) => ({ description: manifest.meta?.description, identifier: manifest.identifier, name: manifest.meta?.title || manifest.identifier, - type: 'klavis' as const, + type: 'composio' as const, })), // Custom connectors (user-added MCP servers) ...connectorManifests.map((manifest) => ({ diff --git a/apps/server/src/services/discover/index.ts b/apps/server/src/services/discover/index.ts index d82a77c81bf..27c7e4eb20e 100644 --- a/apps/server/src/services/discover/index.ts +++ b/apps/server/src/services/discover/index.ts @@ -1,10 +1,10 @@ import { + COMPOSIO_APP_TYPES, CURRENT_VERSION, DEFAULT_DISCOVER_ASSISTANT_ITEM, DEFAULT_DISCOVER_PLUGIN_ITEM, DEFAULT_DISCOVER_PROVIDER_ITEM, isDesktop, - KLAVIS_SERVER_TYPES, } from '@lobechat/const'; import { type AgentStatus, @@ -1165,29 +1165,29 @@ export class DiscoverService { return plugin; } - // Step 4: Try to find in Klavis server types (builtin tools that require env config) - const klavisTool = KLAVIS_SERVER_TYPES.find((tool) => tool.identifier === identifier); - if (klavisTool) { - log('getPluginDetail: found Klavis tool for identifier=%s', identifier); + // Step 4: Try to find in Composio server types (builtin tools that require env config) + const composioTool = COMPOSIO_APP_TYPES.find((tool) => tool.identifier === identifier); + if (composioTool) { + log('getPluginDetail: found Composio tool for identifier=%s', identifier); - // Avatar is empty here because frontend will render Klavis icons using KlavisIcon component + // Avatar is empty here because frontend will render Composio icons using ComposioIcon component // which handles both string URLs and React component icons const plugin: DiscoverPluginDetail = { - author: 'Klavis', - avatar: typeof klavisTool.icon === 'string' ? klavisTool.icon : '', + author: 'Composio', + avatar: typeof composioTool.icon === 'string' ? composioTool.icon : '', category: undefined, createdAt: '', - description: `LobeHub Mcp Server: ${klavisTool.label}`, - homepage: 'https://klavis.ai', - identifier: klavisTool.identifier, + description: `LobeHub Mcp Server: ${composioTool.label}`, + homepage: 'https://composio.dev', + identifier: composioTool.identifier, manifest: undefined, related: [], schemaVersion: 1, source: 'builtin', - tags: ['klavis', 'mcp'], - title: klavisTool.label, + tags: ['composio', 'mcp'], + title: composioTool.label, }; - log('getPluginDetail: returning Klavis tool plugin'); + log('getPluginDetail: returning Composio tool plugin'); return plugin; } diff --git a/apps/server/src/services/heterogeneousAgent/HeterogeneousPersistenceHandler.ts b/apps/server/src/services/heterogeneousAgent/HeterogeneousPersistenceHandler.ts index d780a75b425..6ba05eed902 100644 --- a/apps/server/src/services/heterogeneousAgent/HeterogeneousPersistenceHandler.ts +++ b/apps/server/src/services/heterogeneousAgent/HeterogeneousPersistenceHandler.ts @@ -575,9 +575,16 @@ export class HeterogeneousPersistenceHandler { * * Merge semantics: only runs MISSING from the in-memory map are rehydrated, so * a warm replica's live per-turn accumulators (`accContent`, current - * `toolState`) are never clobbered by the DB projection. Finalized runs are - * excluded (their thread is `Active`, not `Processing`), so a completed spawn - * is never resurrected. + * `toolState`) are never clobbered by the DB projection. + * + * Finalized (`Active`) spawns are NOT rehydrated as live runs (a completed + * spawn is never resurrected — that would mint spurious empty assistants and + * re-finalize churn), but their `sourceToolCallId` IS recorded in + * `finalizedParents` so a REPLAYED first-event on a cold replica can't fork a + * duplicate thread for a spawn that already finished (the "一模一样的两个 + * thread" bug). This mirrors #15838's main-turn idempotency for the subagent + * thread-create step: dedup keyed by the DB-homed `sourceToolCallId`, + * independent of in-memory state and of thread status. * * Best-effort: any DB hiccup (or a partial test mock without the query * methods) leaves `state.main.subagents` untouched rather than aborting the @@ -588,12 +595,13 @@ export class HeterogeneousPersistenceHandler { const threads = await this.deps.threadModel.queryByTopicId(state.topicId); const existing = state.main.subagents.runs; const snapshots: SubagentRunSnapshot[] = []; + // Union with any parents finalized in-memory on a warm replica. + const finalizedParents = new Set(state.main.subagents.finalizedParents); for (const thread of threads ?? []) { if (thread.type !== ThreadType.Isolation) continue; - if (thread.status !== ThreadStatus.Processing) continue; const meta = thread.metadata as { operationId?: string; sourceToolCallId?: string } | null; - // Operation-scoped: only rehydrate threads THIS operation created. + // Operation-scoped: only attend to threads THIS operation created. // Topics are reused across turns, so a prior run that crashed / was // cancelled without an ingested terminal event can leave its subagent // thread stuck in `Processing`. Without this guard the next operation @@ -605,6 +613,13 @@ export class HeterogeneousPersistenceHandler { const parentToolCallId = meta?.sourceToolCallId; if (!parentToolCallId || existing.has(parentToolCallId)) continue; + // Finalized spawn → remember the key (blocks duplicate create), don't + // rehydrate it as a live run. + if (thread.status !== ThreadStatus.Processing) { + finalizedParents.add(parentToolCallId); + continue; + } + const messages = await this.deps.messageModel.query({ threadId: thread.id, topicId: state.topicId, @@ -613,11 +628,20 @@ export class HeterogeneousPersistenceHandler { if (snapshot) snapshots.push(snapshot); } - if (snapshots.length === 0) return; + // Nothing new to project: no rehydratable runs AND no finalized keys + // beyond what memory already tracked (the set started as a copy of it and + // only grows, so an unchanged size means no new Active threads were found). + if ( + snapshots.length === 0 && + finalizedParents.size === state.main.subagents.finalizedParents.size + ) { + return; + } // Union: rehydrated (missing) runs + the in-memory ones (which win, since - // they carry live accumulators the DB hasn't caught up to yet). - const merged = rehydrateSubagentRunsState(snapshots); + // they carry live accumulators the DB hasn't caught up to yet) + the + // finalized-parent guard set. + const merged = rehydrateSubagentRunsState(snapshots, [...finalizedParents]); for (const [parentToolCallId, run] of existing) merged.runs.set(parentToolCallId, run); state.main = { ...state.main, subagents: merged }; } catch (err) { diff --git a/apps/server/src/services/heterogeneousAgent/__tests__/HeterogeneousPersistenceHandler.subagentRehydration.test.ts b/apps/server/src/services/heterogeneousAgent/__tests__/HeterogeneousPersistenceHandler.subagentRehydration.test.ts index de52e34ed06..ff6553374d6 100644 --- a/apps/server/src/services/heterogeneousAgent/__tests__/HeterogeneousPersistenceHandler.subagentRehydration.test.ts +++ b/apps/server/src/services/heterogeneousAgent/__tests__/HeterogeneousPersistenceHandler.subagentRehydration.test.ts @@ -274,6 +274,66 @@ describe('HeterogeneousPersistenceHandler — subagent run survives a cold repli expect([...h.threads.values()].some((t) => t.title === 'Subagent')).toBe(false); }); + // The screenshot bug: a subagent that already FINISHED (its parent + // tool_result landed → thread flipped Active) has its FIRST event replayed on + // a cold replica (BatchIngester retry / re-delivery where the in-memory + // `processedKeys` dedupe is gone). Because finalized threads aren't rehydrated + // as live runs, the empty reducer used to hit `!existing` and fork a SECOND + // thread with the identical title ("一模一样的两个 thread"). The fix records + // the finalized parent's `sourceToolCallId` in `finalizedParents` from the DB + // `Active` thread, so the replayed first-event is a stale no-op. + it('does NOT re-create the thread when a FINISHED subagent replays its first event on a fresh replica', async () => { + const h = createHarness({ + assistantMessageId: 'asst-1', + operationId: 'op-1', + topicId: 'topic-1', + }); + const PARENT = 'tc-spawn-1'; + + const firstChunk = buildEvent('stream_chunk', 0, { + chunkType: 'tools_calling', + subagent: { + parentToolCallId: PARENT, + spawnMetadata: { + description: 'Map client runtime completion paths', + prompt: 'investigate', + subagentType: 'Explore', + }, + subagentMessageId: 'sub-msg-1', + }, + toolsCalling: [innerTool('inner-1')], + }); + + // ── Batch 1 (replica A): subagent runs, then its parent tool_result lands → + // the run finalizes and the thread is flipped Active. ── + await h.handler.ingest({ + assistantMessageId: 'asst-1', + events: [firstChunk, buildEvent('tool_result', 1, { content: 'done', toolCallId: PARENT })], + operationId: 'op-1', + topicId: 'topic-1', + }); + + expect(h.threads.size).toBe(1); + const finishedThreadId = [...h.threads.keys()][0]; + expect(h.threads.get(finishedThreadId)!.status).toBe('active'); + + // ── Cold replica: warm state gone, DB persists. ── + __resetOperationStatesForTesting(); + + // ── Replay of the SAME first event (processedKeys is empty on the fresh + // replica, so it is NOT deduped away — it really re-enters the reducer). ── + await h.handler.ingest({ + assistantMessageId: 'asst-1', + events: [firstChunk], + operationId: 'op-1', + topicId: 'topic-1', + }); + + // Still exactly one thread — no duplicate, no second "Map client runtime…". + expect(h.threads.size).toBe(1); + expect([...h.threads.keys()]).toEqual([finishedThreadId]); + }); + // P1: a tools_calling batch reprocessed on a cold replica (BatchIngester // retry, or a turn split across a cold boundary so the cumulative array is // re-seen) must NOT mint a second tool message for an inner tool the run diff --git a/apps/server/src/services/klavis/index.test.ts b/apps/server/src/services/klavis/index.test.ts deleted file mode 100644 index 0e10ce62e0d..00000000000 --- a/apps/server/src/services/klavis/index.test.ts +++ /dev/null @@ -1,68 +0,0 @@ -// @vitest-environment node -import { beforeEach, describe, expect, it, vi } from 'vitest'; - -import { KlavisService } from './index'; - -const mocks = vi.hoisted(() => ({ - PluginModel: vi.fn(), - pluginQuery: vi.fn(), -})); - -vi.mock('@/database/models/plugin', () => ({ - PluginModel: mocks.PluginModel, -})); - -vi.mock('@/libs/klavis', () => ({ - getKlavisClient: vi.fn(), - isKlavisClientAvailable: vi.fn(() => true), -})); - -vi.mock('debug', () => ({ - default: vi.fn(() => vi.fn()), -})); - -describe('KlavisService', () => { - beforeEach(() => { - vi.clearAllMocks(); - mocks.PluginModel.mockImplementation(() => ({ - query: mocks.pluginQuery, - })); - }); - - describe('getKlavisManifests', () => { - it('filters deprecated Klavis providers from server manifests', async () => { - mocks.pluginQuery.mockResolvedValue([ - { - customParams: { klavis: { isAuthenticated: true, serverName: 'Gmail' } }, - identifier: 'gmail', - manifest: { - api: [{ name: 'sendEmail', parameters: { type: 'object' } }], - meta: { title: 'Gmail' }, - }, - }, - { - customParams: { klavis: { isAuthenticated: true, serverName: 'Notion' } }, - identifier: 'notion', - manifest: { - api: [{ name: 'notion-search', parameters: { type: 'object' } }], - meta: { title: 'Notion' }, - }, - }, - { - customParams: { klavis: { isAuthenticated: false, serverName: 'Google Calendar' } }, - identifier: 'google-calendar', - manifest: { - api: [{ name: 'listEvents', parameters: { type: 'object' } }], - meta: { title: 'Google Calendar' }, - }, - }, - ]); - - const service = new KlavisService({ db: {} as any, userId: 'user-1' }); - - const manifests = await service.getKlavisManifests(); - - expect(manifests.map((manifest) => manifest.identifier)).toEqual(['gmail']); - }); - }); -}); diff --git a/apps/server/src/services/klavis/index.ts b/apps/server/src/services/klavis/index.ts deleted file mode 100644 index bbcea1209d5..00000000000 --- a/apps/server/src/services/klavis/index.ts +++ /dev/null @@ -1,241 +0,0 @@ -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; -import type { LobeToolManifest } from '@lobechat/context-engine'; -import type { LobeChatDatabase } from '@lobechat/database'; -import debug from 'debug'; - -import { PluginModel } from '@/database/models/plugin'; -import { getKlavisClient, isKlavisClientAvailable } from '@/libs/klavis'; -import { type ToolExecutionResult } from '@/server/services/toolExecution/types'; - -const log = debug('lobe-server:klavis-service'); - -const VALID_KLAVIS_IDENTIFIERS = new Set(KLAVIS_SERVER_TYPES.map((type) => type.identifier)); - -export interface KlavisToolExecuteParams { - args: Record; - /** Tool identifier (same as Klavis server identifier, e.g., 'google-calendar') */ - identifier: string; - toolName: string; - workspaceId?: string; -} - -export interface KlavisServiceOptions { - db?: LobeChatDatabase; - userId?: string; - workspaceId?: string; -} - -/** - * Klavis Service - * - * Provides a unified interface to Klavis Client with business logic encapsulation. - * This service wraps Klavis Client methods to execute tools and fetch manifests. - * - * Usage: - * ```typescript - * // With database and userId (for manifest fetching) - * const service = new KlavisService({ db, userId }); - * await service.executeKlavisTool({ identifier, toolName, args }); - * - * // Without database (for tool execution only if you have serverUrl) - * const service = new KlavisService(); - * ``` - */ -export class KlavisService { - private db?: LobeChatDatabase; - private userId?: string; - private pluginModel?: PluginModel; - private workspaceId?: string; - - constructor(options: KlavisServiceOptions = {}) { - const { db, userId, workspaceId } = options; - - this.db = db; - this.userId = userId; - this.workspaceId = workspaceId; - - if (db && userId) { - this.pluginModel = new PluginModel(db, userId, workspaceId); - } - - log( - 'KlavisService initialized: hasDB=%s, hasUserId=%s, isClientAvailable=%s', - !!db, - !!userId, - isKlavisClientAvailable(), - ); - } - - /** - * Execute a Klavis tool - * @param params - Tool execution parameters - * @returns Tool execution result - */ - async executeKlavisTool(params: KlavisToolExecuteParams): Promise { - const { identifier, toolName, args, workspaceId } = params; - - log('executeKlavisTool: %s/%s with args: %O', identifier, toolName, args); - - // Check if Klavis client is available - if (!isKlavisClientAvailable()) { - return { - content: 'Klavis service is not configured on server', - error: { code: 'KLAVIS_NOT_CONFIGURED', message: 'Klavis API key not found' }, - success: false, - }; - } - - // Get serverUrl from plugin database - if (!this.pluginModel) { - return { - content: 'Klavis service is not properly initialized', - error: { - code: 'KLAVIS_NOT_INITIALIZED', - message: 'Database and userId are required for Klavis tool execution', - }, - success: false, - }; - } - - try { - // Get plugin from database to retrieve serverUrl - const pluginModel = - workspaceId && this.db && this.userId - ? new PluginModel(this.db, this.userId, workspaceId) - : this.pluginModel; - const plugin = await pluginModel.findById(identifier); - if (!plugin) { - return { - content: `Klavis server "${identifier}" not found in database`, - error: { code: 'KLAVIS_SERVER_NOT_FOUND', message: `Server ${identifier} not found` }, - success: false, - }; - } - - const klavisParams = plugin.customParams?.klavis; - if (!klavisParams || !klavisParams.serverUrl) { - return { - content: `Klavis configuration not found for server "${identifier}"`, - error: { - code: 'KLAVIS_CONFIG_NOT_FOUND', - message: `Klavis configuration missing for ${identifier}`, - }, - success: false, - }; - } - - const { serverUrl } = klavisParams; - - log('executeKlavisTool: calling Klavis API with serverUrl=%s', serverUrl); - - // Call Klavis client - const klavisClient = getKlavisClient(); - const response = await klavisClient.mcpServer.callTools({ - serverUrl, - toolArgs: args, - toolName, - }); - - log('executeKlavisTool: response: %O', response); - - // Handle error case - if (!response.success || !response.result) { - return { - content: response.error || 'Unknown error', - error: { code: 'KLAVIS_EXECUTION_ERROR', message: response.error || 'Unknown error' }, - success: false, - }; - } - - // Process the response - const content = response.result.content || []; - const isError = response.result.isError || false; - - // Convert content array to string - let resultContent = ''; - if (Array.isArray(content)) { - resultContent = content - .map((item: any) => { - if (typeof item === 'string') return item; - if (item.type === 'text' && item.text) return item.text; - return JSON.stringify(item); - }) - .join('\n'); - } else if (typeof content === 'string') { - resultContent = content; - } else { - resultContent = JSON.stringify(content); - } - - return { - content: resultContent, - success: !isError, - }; - } catch (error) { - const err = error as Error; - console.error('KlavisService.executeKlavisTool error %s/%s: %O', identifier, toolName, err); - - return { - content: err.message, - error: { code: 'KLAVIS_ERROR', message: err.message }, - success: false, - }; - } - } - - /** - * Fetch Klavis tool manifests from database - * Gets user's connected Klavis servers and builds tool manifests for agent execution - * - * @returns Array of tool manifests for connected Klavis servers - */ - async getKlavisManifests(): Promise { - if (!this.pluginModel) { - log('getKlavisManifests: pluginModel not available, returning empty array'); - return []; - } - - try { - // Get all plugins from database - const allPlugins = await this.pluginModel.query(); - - // Filter plugins that have klavis customParams, are still supported, and are authenticated. - const klavisPlugins = allPlugins.filter( - (plugin) => - VALID_KLAVIS_IDENTIFIERS.has(plugin.identifier) && - plugin.customParams?.klavis?.isAuthenticated === true, - ); - - log('getKlavisManifests: found %d authenticated Klavis plugins', klavisPlugins.length); - - // Convert to LobeToolManifest format - const manifests: LobeToolManifest[] = klavisPlugins - .map((plugin) => { - if (!plugin.manifest) return null; - - return { - api: plugin.manifest.api || [], - author: 'Klavis', - homepage: 'https://klavis.ai', - identifier: plugin.identifier, - meta: plugin.manifest.meta || { - avatar: '☁️', - description: `Klavis MCP Server: ${plugin.customParams?.klavis?.serverName}`, - tags: ['klavis', 'mcp'], - title: plugin.customParams?.klavis?.serverName || plugin.identifier, - }, - type: 'builtin', - version: '1.0.0', - }; - }) - .filter(Boolean) as LobeToolManifest[]; - - log('getKlavisManifests: returning %d manifests', manifests.length); - - return manifests; - } catch (error) { - console.error('KlavisService.getKlavisManifests error: %O', error); - return []; - } - } -} diff --git a/apps/server/src/services/mcp/index.ts b/apps/server/src/services/mcp/index.ts index e33856f2406..38712a382cd 100644 --- a/apps/server/src/services/mcp/index.ts +++ b/apps/server/src/services/mcp/index.ts @@ -56,7 +56,7 @@ export class MCPService { /** * Process MCP tool call result with content blocks processing - * This is a common utility method that can be used by both internal MCP calls and external services (e.g., Klavis) + * This is a common utility method that can be used by both internal MCP calls and external services (e.g., Composio) */ static async processToolCallResult( result: MCPToolCallRawResult, diff --git a/apps/server/src/services/taskTemplate/index.test.ts b/apps/server/src/services/taskTemplate/index.test.ts index 73419d4e5ce..37bc88d31d8 100644 --- a/apps/server/src/services/taskTemplate/index.test.ts +++ b/apps/server/src/services/taskTemplate/index.test.ts @@ -281,19 +281,19 @@ describe('isTemplateSkillSourceEligible', () => { it('drops templates whose source is not in enabledSkillSources', () => { const t = makeTemplate({ requiresSkills: [{ provider: 'notion', source: 'lobehub' }] }); - expect(isTemplateSkillSourceEligible(t, new Set(['klavis']))).toBe(false); + expect(isTemplateSkillSourceEligible(t, new Set(['composio']))).toBe(false); }); it('requires every source for multi-skill templates', () => { const t = makeTemplate({ requiresSkills: [ { provider: 'notion', source: 'lobehub' }, - { provider: 'google-calendar', source: 'klavis' }, + { provider: 'google-calendar', source: 'composio' }, ], }); expect(isTemplateSkillSourceEligible(t, new Set(['lobehub']))).toBe(false); - expect(isTemplateSkillSourceEligible(t, new Set(['klavis']))).toBe(false); - expect(isTemplateSkillSourceEligible(t, new Set(['lobehub', 'klavis']))).toBe(true); + expect(isTemplateSkillSourceEligible(t, new Set(['composio']))).toBe(false); + expect(isTemplateSkillSourceEligible(t, new Set(['lobehub', 'composio']))).toBe(true); }); it('treats empty requiresSkills array same as undefined (always eligible)', () => { diff --git a/apps/server/src/services/taskTemplate/index.ts b/apps/server/src/services/taskTemplate/index.ts index 34f6978dc3e..5136a21c5e0 100644 --- a/apps/server/src/services/taskTemplate/index.ts +++ b/apps/server/src/services/taskTemplate/index.ts @@ -6,12 +6,12 @@ import { taskTemplates, } from '@lobechat/const'; -import { klavisEnv } from '@/config/klavis'; +import { composioEnv } from '@/config/composio'; import { appEnv } from '@/envs/app'; export const ENABLED_SKILL_SOURCES: ReadonlySet = (() => { const sources = new Set(); - if (klavisEnv.KLAVIS_API_KEY) sources.add('klavis'); + if (composioEnv.COMPOSIO_API_KEY) sources.add('composio'); if (appEnv.MARKET_TRUSTED_CLIENT_ID && appEnv.MARKET_TRUSTED_CLIENT_SECRET) { sources.add('lobehub'); } diff --git a/apps/server/src/services/toolExecution/__tests__/builtin.test.ts b/apps/server/src/services/toolExecution/__tests__/builtin.test.ts index 8b954c7b776..8a313deef44 100644 --- a/apps/server/src/services/toolExecution/__tests__/builtin.test.ts +++ b/apps/server/src/services/toolExecution/__tests__/builtin.test.ts @@ -11,8 +11,8 @@ vi.mock('../serverRuntimes', () => ({ getServerRuntime: vi.fn(async () => ({ createDocument: mockApiHandler })), })); -vi.mock('@/server/services/klavis', () => ({ - KlavisService: vi.fn().mockImplementation(() => ({})), +vi.mock('@/server/services/composio', () => ({ + ComposioService: vi.fn().mockImplementation(() => ({})), })); vi.mock('@/server/services/market', () => ({ MarketService: vi.fn().mockImplementation(() => ({})), diff --git a/apps/server/src/services/toolExecution/builtin.ts b/apps/server/src/services/toolExecution/builtin.ts index 45cc7bc55b7..b51bbac56d4 100644 --- a/apps/server/src/services/toolExecution/builtin.ts +++ b/apps/server/src/services/toolExecution/builtin.ts @@ -3,7 +3,7 @@ import { type ChatToolPayload } from '@lobechat/types'; import { detectTruncatedJSON, safeParseJSON } from '@lobechat/utils'; import debug from 'debug'; -import { KlavisService } from '@/server/services/klavis'; +import { ComposioService } from '@/server/services/composio'; import { MarketService } from '@/server/services/market'; import { getServerRuntime, hasServerRuntime } from './serverRuntimes'; @@ -13,11 +13,11 @@ const log = debug('lobe-server:builtin-tools-executor'); export class BuiltinToolsExecutor implements IToolExecutor { private marketService: MarketService; - private klavisService: KlavisService; + private composioService: ComposioService; constructor(db: LobeChatDatabase, userId: string) { this.marketService = new MarketService({ userInfo: { userId } }); - this.klavisService = new KlavisService({ db, userId }); + this.composioService = new ComposioService({ db, userId }); } async execute( @@ -78,13 +78,12 @@ export class BuiltinToolsExecutor implements IToolExecutor { }); } - // Route Klavis tools to KlavisService - if (source === 'klavis') { - return this.klavisService.executeKlavisTool({ + // Route Composio tools to ComposioService + if (source === 'composio') { + return this.composioService.executeComposioTool({ args, identifier, - toolName: apiName, - workspaceId: context.workspaceId, + toolSlug: apiName, }); } diff --git a/apps/server/src/services/toolExecution/index.ts b/apps/server/src/services/toolExecution/index.ts index e20b2c06844..b9dfc9e58e0 100644 --- a/apps/server/src/services/toolExecution/index.ts +++ b/apps/server/src/services/toolExecution/index.ts @@ -82,7 +82,7 @@ export class ToolExecutionService { // ── Connector tool permission gate (covers ALL paths + qstash) ──────── // Check before any execution so that disabled tools are blocked universally: - // Lobehub market skills, Klavis, MCP connectors, and execAgent/qstash alike. + // Lobehub market skills, Composio, MCP connectors, and execAgent/qstash alike. // needs_approval is handled via humanIntervention in the manifest; we only // hard-block 'disabled' here (and needs_approval in headless/qstash context // since the manifest's humanIntervention auto-rejects them there already). diff --git a/apps/server/src/services/toolExecution/serverRuntimes/agentBuilder.ts b/apps/server/src/services/toolExecution/serverRuntimes/agentBuilder.ts index f4c011364a7..6e0783967b7 100644 --- a/apps/server/src/services/toolExecution/serverRuntimes/agentBuilder.ts +++ b/apps/server/src/services/toolExecution/serverRuntimes/agentBuilder.ts @@ -307,9 +307,9 @@ export const agentBuilderRuntime: ServerRuntimeRegistration = { } } - // OAuth-based tools (Klavis, LobehubSkill) cannot be installed in background context + // OAuth-based tools (Composio, LobehubSkill) cannot be installed in background context return { - content: `Installing official integrations that require OAuth (Klavis, LobehubSkill) is not supported in background execution. Please install "${identifier}" from the Agent Builder UI instead.`, + content: `Installing official integrations that require OAuth (Composio, LobehubSkill) is not supported in background execution. Please install "${identifier}" from the Agent Builder UI instead.`, error: { message: 'OAuth not available in background context', type: 'NotSupported' }, success: false, }; diff --git a/docs/development/basic/chat-api.mdx b/docs/development/basic/chat-api.mdx index 0b099c6554b..4a4c31282da 100644 --- a/docs/development/basic/chat-api.mdx +++ b/docs/development/basic/chat-api.mdx @@ -169,7 +169,7 @@ executed directly via local executors. - Frontend calls `MCPService` (`src/services/mcp.ts`) via the `invokeMCPTypePlugin` method - Supports three connection modes: - stdio, HTTP (streamable-http/SSE), and cloud (Klavis) + stdio, HTTP (streamable-http/SSE), and cloud (Composio) - MCP tool registration and discovery is managed through MCP server configuration diff --git a/docs/development/basic/chat-api.zh-CN.mdx b/docs/development/basic/chat-api.zh-CN.mdx index 5bdb3f161d0..af7ac93a186 100644 --- a/docs/development/basic/chat-api.zh-CN.mdx +++ b/docs/development/basic/chat-api.zh-CN.mdx @@ -153,7 +153,7 @@ while (state.status !== 'done' && state.status !== 'error') { - 前端通过 `invokeMCPTypePlugin` 方法调用 `MCPService`(`src/services/mcp.ts`) - 支持 stdio、HTTP(streamable-http/SSE) - 和云端(Klavis)三种连接方式 + 和云端(Composio)三种连接方式 - MCP 工具的注册和发现通过 MCP 服务器配置管理 **Plugin 工具**:传统插件体系,通过 API 网关调用。 diff --git a/docs/development/basic/folder-structure.mdx b/docs/development/basic/folder-structure.mdx index 2845214edc5..b7151b86f94 100644 --- a/docs/development/basic/folder-structure.mdx +++ b/docs/development/basic/folder-structure.mdx @@ -136,7 +136,7 @@ app/ topic, file, knowledge, settings, etc.) - `async/` — Long-running async operations (file processing, image generation, RAG evaluation) - - `tools/` — Tool invocations (search, MCP, market, klavis) + - `tools/` — Tool invocations (search, MCP, market, composio) - `mobile/` — Mobile-specific routers **Data Flow:** diff --git a/docs/development/basic/folder-structure.zh-CN.mdx b/docs/development/basic/folder-structure.zh-CN.mdx index 75c25c9f236..3f06e7fccd0 100644 --- a/docs/development/basic/folder-structure.zh-CN.mdx +++ b/docs/development/basic/folder-structure.zh-CN.mdx @@ -132,7 +132,7 @@ app/ - `lambda/` — 主要业务路由(agent、session、message、 topic、file、knowledge、settings 等) - `async/` — 耗时异步操作(文件处理、图像生成、RAG 评估) - - `tools/` — 工具调用(search、MCP、market、klavis) + - `tools/` — 工具调用(search、MCP、market、composio) - `mobile/` — 移动端专用路由 **数据流:** diff --git a/docs/usage/community/skill-management.mdx b/docs/usage/community/skill-management.mdx index b415ddfce34..fd5252f16d4 100644 --- a/docs/usage/community/skill-management.mdx +++ b/docs/usage/community/skill-management.mdx @@ -30,7 +30,7 @@ Every skill exposes one or more **tools**. The Agent decides when to call a tool | ------------------------ | ------------------------------------ | ----------------------------------------- | | **Built-in tools** | Capabilities built into LobeHub | Artifacts, Sandbox, GTD, Notebook, Memory | | **LobeHub Integrations** | OAuth-connected third-party services | Linear, Microsoft, Twitter | -| **Klavis** | Klavis-powered integrations | Gmail, Notion, Slack, and more | +| **Composio** | Composio-powered integrations | Gmail, Notion, Slack, and more | | **Community MCP** | MCP servers from the MCP Marketplace | GitHub, PostgreSQL, Brave Search | | **Custom MCP** | MCP servers you add manually | Your own APIs, private tools | @@ -44,7 +44,7 @@ The Skill Store is where you discover and install skills. Open it from: The Skill Store has three tabs: -- **LobeHub** — Built-in tools and LobeHub-native integrations (Linear, Microsoft, Twitter, Klavis services) +- **LobeHub** — Built-in tools and LobeHub-native integrations (Linear, Microsoft, Twitter, Composio services) - **Community** — MCPs from the [MCP Marketplace](/docs/usage/community/mcp-market), covering thousands of services - **Custom** — MCP servers you've added manually, plus an **Add custom skill** button @@ -54,7 +54,7 @@ Use the search bar to filter across all tabs by keyword. ### Built-in tools and Integrations -Built-in tools (Artifacts, Sandbox, GTD, Notebook) are pre-installed — you can enable them for any Agent immediately. LobeHub Integrations and Klavis services require an OAuth connection: +Built-in tools (Artifacts, Sandbox, GTD, Notebook) are pre-installed — you can enable them for any Agent immediately. LobeHub Integrations and Composio services require an OAuth connection: 1. In the Skill Store, go to the **LobeHub** tab 2. Find the integration you want (e.g. Linear, Gmail) @@ -87,7 +87,7 @@ See the [Custom MCP](/docs/usage/community/custom-mcp) guide for a full walkthro Skills are grouped into three categories: -**Integrations** — Built-in tools, LobeHub-connected services, and Klavis integrations. Each shows its connection status. Click **Connect** or **Disconnect** to manage the OAuth link. +**Integrations** — Built-in tools, LobeHub-connected services, and Composio integrations. Each shows its connection status. Click **Connect** or **Disconnect** to manage the OAuth link. **Community MCPs** — MCP servers installed from the marketplace. Each shows its connection type (HTTP or STDIO). Click **Configure** to edit the connection URL or authentication, or to view the tools it provides. diff --git a/docs/usage/community/skill-management.zh-CN.mdx b/docs/usage/community/skill-management.zh-CN.mdx index 262a495c6f4..9ba722865db 100644 --- a/docs/usage/community/skill-management.zh-CN.mdx +++ b/docs/usage/community/skill-management.zh-CN.mdx @@ -28,7 +28,7 @@ tags: | -------------- | ------------------ | -------------------------- | | **内置工具** | LobeHub 内置的能力 | Artifacts、沙盒、GTD、笔记本、记忆 | | **LobeHub 集成** | 通过 OAuth 连接的第三方服务 | Linear、Microsoft、Twitter | -| **Klavis** | Klavis 提供的集成 | Gmail、Notion、Slack 等 | +| **Composio** | Composio 提供的集成 | Gmail、Notion、Slack 等 | | **社区 MCP** | 来自 MCP 市场的 MCP 服务器 | GitHub、PostgreSQL、Brave 搜索 | | **自定义 MCP** | 你手动添加的 MCP 服务器 | 私有 API、内部工具 | @@ -42,7 +42,7 @@ tags: 技能商店有三个标签页: -- **LobeHub** — 内置工具和 LobeHub 原生集成(Linear、Microsoft、Twitter、Klavis 服务等) +- **LobeHub** — 内置工具和 LobeHub 原生集成(Linear、Microsoft、Twitter、Composio 服务等) - **社区** — 来自 [MCP 市场](/zh/docs/usage/community/mcp-market)的 MCP,涵盖数千种服务 - **自定义** — 你手动添加的 MCP 服务器,以及**添加自定义技能**按钮 @@ -52,7 +52,7 @@ tags: ### 内置工具与集成 -内置工具(Artifacts、沙盒、GTD、笔记本)已预装,可直接为任意助理启用。LobeHub 集成和 Klavis 服务需要先完成 OAuth 授权: +内置工具(Artifacts、沙盒、GTD、笔记本)已预装,可直接为任意助理启用。LobeHub 集成和 Composio 服务需要先完成 OAuth 授权: 1. 在技能商店中,进入 **LobeHub** 标签页 2. 找到需要的集成(如 Linear、Gmail) @@ -85,7 +85,7 @@ tags: 技能按以下三个分类展示: -**集成** — 内置工具、LobeHub 连接的服务和 Klavis 集成,每项显示连接状态。点击**连接**或**断开连接**管理 OAuth 授权。 +**集成** — 内置工具、LobeHub 连接的服务和 Composio 集成,每项显示连接状态。点击**连接**或**断开连接**管理 OAuth 授权。 **社区 MCP** — 从市场安装的 MCP 服务器,每项显示连接类型(HTTP 或 STDIO)。点击**配置**可编辑连接 URL 或认证信息,或查看提供的工具列表。 diff --git a/locales/ar/setting.json b/locales/ar/setting.json index cc46638ce23..9dead4f6b63 100644 --- a/locales/ar/setting.json +++ b/locales/ar/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "إلغاء تثبيت {{name}}", "tools.builtins.uninstalled": "تم إلغاء التثبيت", "tools.disabled": "النموذج الحالي لا يدعم استدعاء الوظائف ولا يمكنه استخدام المهارة", - "tools.klavis.addServer": "إضافة خادم", - "tools.klavis.authCompleted": "تم التحقق من الهوية", - "tools.klavis.authFailed": "فشل التحقق من الهوية", - "tools.klavis.authRequired": "التحقق من الهوية مطلوب", - "tools.klavis.connect": "اتصال", - "tools.klavis.connected": "متصل", - "tools.klavis.disconnect": "قطع الاتصال", - "tools.klavis.disconnected": "غير متصل", - "tools.klavis.error": "خطأ", - "tools.klavis.groupName": "أدوات Klavis", - "tools.klavis.manage": "إدارة Klavis", - "tools.klavis.manageTitle": "إدارة تكامل Klavis", - "tools.klavis.noServers": "لا توجد خوادم متصلة", - "tools.klavis.notEnabled": "خدمة Klavis غير مفعلة", - "tools.klavis.oauthRequired": "يرجى إكمال التحقق من OAuth في النافذة الجديدة", - "tools.klavis.pendingAuth": "في انتظار التحقق", - "tools.klavis.remove": "إزالة", - "tools.klavis.removeConfirm.desc": "سيتم إزالة {{name}} نهائيًا من خدماتك المتصلة. لا يمكن التراجع عن هذا الإجراء.", - "tools.klavis.removeConfirm.title": "إزالة {{name}}؟", - "tools.klavis.serverCreated": "تم إنشاء الخادم بنجاح", - "tools.klavis.serverCreatedFailed": "فشل في إنشاء الخادم", - "tools.klavis.serverRemoved": "تمت إزالة الخادم", - "tools.klavis.servers": "الخوادم", - "tools.klavis.servers.airtable.description": "Airtable هي منصة قواعد بيانات وجداول بيانات سحابية تجمع بين مرونة الجداول وقوة قواعد البيانات، مما يمكّن الفرق من تنظيم المشاريع وتتبعها والتعاون فيها من خلال طرق عرض قابلة للتخصيص وميزات أتمتة قوية.", - "tools.klavis.servers.airtable.readme": "تكامل مع Airtable لإدارة قواعد البيانات وسير العمل. استعلم عن السجلات، وأنشئ إدخالات، وحدث البيانات، وأتمت العمليات باستخدام طرق عرض قابلة للتخصيص وميزات تتبع قوية.", - "tools.klavis.servers.cal-com.description": "Cal.com هي منصة جدولة مفتوحة المصدر تساعدك على تحديد مواعيد الاجتماعات دون الحاجة إلى تبادل الرسائل الإلكترونية. إدارة أنواع الفعاليات، الحجوزات، التوفر، والتكامل مع التقويمات لتحديد المواعيد بسلاسة.", - "tools.klavis.servers.cal-com.readme": "اتصل بـ Cal.com لإدارة جدولك ومواعيدك. اعرض التوفر، واحجز الاجتماعات، وأدر أنواع الفعاليات، وأتمت تقويمك من خلال المحادثة الطبيعية.", - "tools.klavis.servers.clickup.description": "ClickUp هي منصة شاملة لإدارة المشاريع والإنتاجية تساعد الفرق على تنظيم المهام، إدارة المشاريع، والتعاون بفعالية من خلال سير عمل قابل للتخصيص وميزات تتبع قوية.", - "tools.klavis.servers.clickup.readme": "اتصل بـ ClickUp لإدارة المهام، وتتبع المشاريع، وتنظيم عملك. أنشئ مهام، وحدث الحالات، وأدر سير العمل المخصص، وتعاون مع فريقك باستخدام أوامر اللغة الطبيعية.", - "tools.klavis.servers.confluence.description": "Confluence هي مساحة عمل جماعية حيث يلتقي التعاون والمعرفة.", - "tools.klavis.servers.confluence.readme": "اتصل بـ Confluence للوصول إلى مستندات الفريق وإدارتها. ابحث في الصفحات، وأنشئ محتوى، ونظّم المساحات، وابنِ قاعدة معرفتك بمساعدة الذكاء الاصطناعي الحواري.", - "tools.klavis.servers.dropbox.description": "حل متكامل لإدارة الملفات على Dropbox. رفع، تنزيل، تنظيم الملفات والمجلدات، إدارة المشاركة والتعاون، التعامل مع إصدارات الملفات، إنشاء طلبات الملفات، وتنفيذ عمليات مجمعة على ملفاتك.", - "tools.klavis.servers.dropbox.readme": "تكامل مع Dropbox للوصول إلى ملفاتك وإدارتها. حمّل، ونزّل، وشارك الملفات، وأدر المجلدات، وتابع نسخ الملفات، ونظّم تخزينك السحابي من خلال الذكاء الاصطناعي الحواري.", - "tools.klavis.servers.figma.description": "Figma هي أداة تصميم واجهات تعاونية لتطبيقات الويب والجوال.", - "tools.klavis.servers.figma.readme": "اتصل بـ Figma للوصول إلى ملفات التصميم والتعاون في المشاريع. اعرض التصاميم، وصدّر العناصر، وتصفح المكونات، وأدر سير عمل التصميم من خلال المحادثة الطبيعية.", - "tools.klavis.servers.github.description": "خادم GitHub MCP المحسن", - "tools.klavis.servers.github.readme": "اتصل بـ GitHub لإدارة المستودعات، والمشكلات، وطلبات السحب، والتعليمات البرمجية. ابحث في الكود، وراجع التغييرات، وأنشئ فروعًا، وتعاون في مشاريع تطوير البرمجيات من خلال الذكاء الاصطناعي الحواري.", - "tools.klavis.servers.gmail.description": "Gmail هي خدمة بريد إلكتروني مجانية مقدمة من Google", - "tools.klavis.servers.gmail.readme": "اجلب قوة Gmail مباشرة إلى مساعدك الذكي. اقرأ، واكتب، وأرسل رسائل البريد الإلكتروني، وابحث في صندوق الوارد، وأدر التصنيفات، ونظّم اتصالاتك — كل ذلك من خلال المحادثة الطبيعية.", - "tools.klavis.servers.google-calendar.description": "تقويم Google هو خدمة تقويم لإدارة الوقت والجدولة", - "tools.klavis.servers.google-calendar.readme": "تكامل مع تقويم Google لعرض وإنشاء وإدارة فعالياتك بسلاسة. جدْوِل الاجتماعات، واضبط التذكيرات، وتحقق من التوفر، ونظّم وقتك — كل ذلك باستخدام أوامر اللغة الطبيعية.", - "tools.klavis.servers.google-docs.description": "محرر مستندات Google هو معالج نصوص ضمن مجموعة Google Docs المجانية على الويب", - "tools.klavis.servers.google-docs.readme": "تكامل مع مستندات Google لإنشاء وتحرير وإدارة المستندات. اكتب المحتوى، ونسّق النص، وتعاون في الوقت الفعلي، وادخل إلى مستنداتك من خلال المحادثة الطبيعية.", - "tools.klavis.servers.google-drive.description": "Google Drive هي خدمة تخزين سحابي", - "tools.klavis.servers.google-drive.readme": "اتصل بـ Google Drive للوصول إلى ملفاتك وتنظيمها وإدارتها. ابحث في المستندات، وحمّل الملفات، وشارك المحتوى، وتصفح التخزين السحابي بكفاءة بمساعدة الذكاء الاصطناعي.", - "tools.klavis.servers.google-sheets.description": "جداول بيانات Google هي تطبيق جداول بيانات عبر الإنترنت يتيح للمستخدمين إنشاء وتحرير والتعاون في الجداول.", - "tools.klavis.servers.google-sheets.readme": "اتصل بـ Google Sheets لقراءة وكتابة وتحليل بيانات الجداول. نفّذ الحسابات، وأنشئ التقارير، وارسم المخططات، وأدر البيانات الجدولية بالتعاون مع الذكاء الاصطناعي.", - "tools.klavis.servers.hubspot.description": "HubSpot هي شركة تطوير وتسويق برمجيات للتسويق الداخلي والمبيعات وخدمة العملاء", - "tools.klavis.servers.hubspot.readme": "تكامل مع HubSpot لإدارة جهات الاتصال، والصفقات، والحملات التسويقية. ادخل إلى بيانات CRM، وتتبع خطوط المبيعات، وأتمت سير العمل، وسهّل عمليات المبيعات والتسويق.", - "tools.klavis.servers.jira.description": "Jira هي أداة لإدارة المشاريع وتتبع القضايا طورتها Atlassian", - "tools.klavis.servers.jira.readme": "تكامل مع Jira لإدارة المشكلات، وتتبع التقدم، وتنظيم السبرينت. أنشئ التذاكر، وحدث الحالات، واستعلم عن بيانات المشاريع، وسهّل سير عمل التطوير من خلال المحادثة الطبيعية.", - "tools.klavis.servers.notion.description": "Notion هو تطبيق إنتاجية وتدوين ملاحظات تعاوني", - "tools.klavis.servers.notion.readme": "اتصل بـ Notion للوصول إلى مساحة عملك وإدارتها. أنشئ الصفحات، وابحث في المحتوى، وحدث قواعد البيانات، ونظّم قاعدة معرفتك — كل ذلك من خلال محادثة طبيعية مع مساعدك الذكي.", - "tools.klavis.servers.onedrive.description": "OneDrive هي خدمة استضافة ومزامنة ملفات تديرها Microsoft", - "tools.klavis.servers.onedrive.readme": "اتصل بـ OneDrive للوصول إلى ملفاتك السحابية من Microsoft وإدارتها. حمّل، ونزّل، وشارك الملفات، ونظّم المجلدات، وتعاون في المستندات بمساعدة الذكاء الاصطناعي.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail هي مجموعة خدمات بريد إلكتروني وجهات اتصال ومهام وتقويم عبر الإنترنت من Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "تكامل مع بريد Outlook لقراءة وإرسال وإدارة رسائل البريد الإلكتروني من Microsoft. ابحث في الرسائل، واكتب الرسائل، وأدر المجلدات، ونظّم صندوق الوارد من خلال المحادثة الطبيعية.", - "tools.klavis.servers.salesforce.description": "Salesforce هي المنصة الرائدة عالميًا لإدارة علاقات العملاء (CRM) التي تساعد الشركات على التواصل مع العملاء والشركاء والعملاء المحتملين", - "tools.klavis.servers.salesforce.readme": "اتصل بـ Salesforce لإدارة علاقات العملاء وبيانات المبيعات. استعلم عن السجلات، وحدث الفرص، وتتبع العملاء المحتملين، وأتمت سير عمل CRM باستخدام أوامر اللغة الطبيعية.", - "tools.klavis.servers.slack.description": "Slack هو تطبيق مراسلة للأعمال يربط الأشخاص بالمعلومات التي يحتاجونها", - "tools.klavis.servers.slack.readme": "تكامل مع Slack لإرسال الرسائل، والبحث في المحادثات، وإدارة القنوات. تواصل مع فريقك، وأتمت سير العمل في التواصل، وادخل إلى معلومات مساحة العمل من خلال اللغة الطبيعية.", - "tools.klavis.servers.supabase.description": "خادم Supabase MCP الرسمي", - "tools.klavis.servers.supabase.readme": "تكامل مع Supabase لإدارة قاعدة البيانات وخدمات الخلفية. استعلم عن البيانات، وأدر المصادقة، وتعامل مع التخزين، وتفاعل مع خلفية تطبيقك من خلال المحادثة الطبيعية.", - "tools.klavis.servers.whatsapp.description": "تكامل مع واجهة WhatsApp Business API لإرسال الرسائل النصية والوسائط وإدارة المحادثات مع العملاء. مثالي لدعم العملاء، حملات التسويق، وسير العمل الآلي للرسائل من خلال منصة WhatsApp الرسمية.", - "tools.klavis.servers.whatsapp.readme": "تكامل مع WhatsApp Business لإرسال الرسائل، وإدارة المحادثات، والتفاعل مع العملاء. أتمت سير العمل في المراسلة وتعامل مع الاتصالات من خلال الذكاء الاصطناعي الحواري.", - "tools.klavis.servers.youtube.description": "YouTube هي منصة لمشاركة الفيديوهات حيث يمكن للمستخدمين رفع، مشاركة، واكتشاف المحتوى. الوصول إلى معلومات الفيديو، النصوص، والبيانات الوصفية برمجيًا.", - "tools.klavis.servers.youtube.readme": "اتصل بـ YouTube للبحث عن الفيديوهات، والوصول إلى النصوص، واسترجاع معلومات الفيديو. حلل المحتوى، واستخرج البيانات الوصفية، واكتشف الفيديوهات من خلال المحادثة الطبيعية.", - "tools.klavis.servers.zendesk.description": "Zendesk هي شركة برمجيات لخدمة العملاء", - "tools.klavis.servers.zendesk.readme": "تكامل مع Zendesk لإدارة تذاكر الدعم وتفاعلات العملاء. أنشئ الطلبات، وحدثها، وتتبعها، وادخل إلى بيانات العملاء، وسهّل عمليات الدعم.", - "tools.klavis.tools": "الأدوات", - "tools.klavis.verifyAuth": "لقد أكملت التحقق", + "tools.composio.addServer": "إضافة خادم", + "tools.composio.authCompleted": "تم التحقق من الهوية", + "tools.composio.authFailed": "فشل التحقق من الهوية", + "tools.composio.authRequired": "التحقق من الهوية مطلوب", + "tools.composio.connect": "اتصال", + "tools.composio.connected": "متصل", + "tools.composio.disconnect": "قطع الاتصال", + "tools.composio.disconnected": "غير متصل", + "tools.composio.error": "خطأ", + "tools.composio.groupName": "أدوات Composio", + "tools.composio.manage": "إدارة Composio", + "tools.composio.manageTitle": "إدارة تكامل Composio", + "tools.composio.noServers": "لا توجد خوادم متصلة", + "tools.composio.notEnabled": "خدمة Composio غير مفعلة", + "tools.composio.oauthRequired": "يرجى إكمال التحقق من OAuth في النافذة الجديدة", + "tools.composio.pendingAuth": "في انتظار التحقق", + "tools.composio.serverCreated": "تم إنشاء الخادم بنجاح", + "tools.composio.serverCreatedFailed": "فشل في إنشاء الخادم", + "tools.composio.serverRemoved": "تمت إزالة الخادم", + "tools.composio.servers": "الخوادم", + "tools.composio.servers.airtable.description": "Airtable هي منصة قواعد بيانات وجداول بيانات سحابية تجمع بين مرونة الجداول وقوة قواعد البيانات، مما يمكّن الفرق من تنظيم المشاريع وتتبعها والتعاون فيها من خلال طرق عرض قابلة للتخصيص وميزات أتمتة قوية.", + "tools.composio.servers.airtable.readme": "تكامل مع Airtable لإدارة قواعد البيانات وسير العمل. استعلم عن السجلات، وأنشئ إدخالات، وحدث البيانات، وأتمت العمليات باستخدام طرق عرض قابلة للتخصيص وميزات تتبع قوية.", + "tools.composio.servers.cal-com.description": "Cal.com هي منصة جدولة مفتوحة المصدر تساعدك على تحديد مواعيد الاجتماعات دون الحاجة إلى تبادل الرسائل الإلكترونية. إدارة أنواع الفعاليات، الحجوزات، التوفر، والتكامل مع التقويمات لتحديد المواعيد بسلاسة.", + "tools.composio.servers.cal-com.readme": "اتصل بـ Cal.com لإدارة جدولك ومواعيدك. اعرض التوفر، واحجز الاجتماعات، وأدر أنواع الفعاليات، وأتمت تقويمك من خلال المحادثة الطبيعية.", + "tools.composio.servers.clickup.description": "ClickUp هي منصة شاملة لإدارة المشاريع والإنتاجية تساعد الفرق على تنظيم المهام، إدارة المشاريع، والتعاون بفعالية من خلال سير عمل قابل للتخصيص وميزات تتبع قوية.", + "tools.composio.servers.clickup.readme": "اتصل بـ ClickUp لإدارة المهام، وتتبع المشاريع، وتنظيم عملك. أنشئ مهام، وحدث الحالات، وأدر سير العمل المخصص، وتعاون مع فريقك باستخدام أوامر اللغة الطبيعية.", + "tools.composio.servers.confluence.description": "Confluence هي مساحة عمل جماعية حيث يلتقي التعاون والمعرفة.", + "tools.composio.servers.confluence.readme": "اتصل بـ Confluence للوصول إلى مستندات الفريق وإدارتها. ابحث في الصفحات، وأنشئ محتوى، ونظّم المساحات، وابنِ قاعدة معرفتك بمساعدة الذكاء الاصطناعي الحواري.", + "tools.composio.servers.dropbox.description": "حل متكامل لإدارة الملفات على Dropbox. رفع، تنزيل، تنظيم الملفات والمجلدات، إدارة المشاركة والتعاون، التعامل مع إصدارات الملفات، إنشاء طلبات الملفات، وتنفيذ عمليات مجمعة على ملفاتك.", + "tools.composio.servers.dropbox.readme": "تكامل مع Dropbox للوصول إلى ملفاتك وإدارتها. حمّل، ونزّل، وشارك الملفات، وأدر المجلدات، وتابع نسخ الملفات، ونظّم تخزينك السحابي من خلال الذكاء الاصطناعي الحواري.", + "tools.composio.servers.figma.description": "Figma هي أداة تصميم واجهات تعاونية لتطبيقات الويب والجوال.", + "tools.composio.servers.figma.readme": "اتصل بـ Figma للوصول إلى ملفات التصميم والتعاون في المشاريع. اعرض التصاميم، وصدّر العناصر، وتصفح المكونات، وأدر سير عمل التصميم من خلال المحادثة الطبيعية.", + "tools.composio.servers.github.description": "خادم GitHub MCP المحسن", + "tools.composio.servers.github.readme": "اتصل بـ GitHub لإدارة المستودعات، والمشكلات، وطلبات السحب، والتعليمات البرمجية. ابحث في الكود، وراجع التغييرات، وأنشئ فروعًا، وتعاون في مشاريع تطوير البرمجيات من خلال الذكاء الاصطناعي الحواري.", + "tools.composio.servers.gmail.description": "Gmail هي خدمة بريد إلكتروني مجانية مقدمة من Google", + "tools.composio.servers.gmail.readme": "اجلب قوة Gmail مباشرة إلى مساعدك الذكي. اقرأ، واكتب، وأرسل رسائل البريد الإلكتروني، وابحث في صندوق الوارد، وأدر التصنيفات، ونظّم اتصالاتك — كل ذلك من خلال المحادثة الطبيعية.", + "tools.composio.servers.google-calendar.description": "تقويم Google هو خدمة تقويم لإدارة الوقت والجدولة", + "tools.composio.servers.google-calendar.readme": "تكامل مع تقويم Google لعرض وإنشاء وإدارة فعالياتك بسلاسة. جدْوِل الاجتماعات، واضبط التذكيرات، وتحقق من التوفر، ونظّم وقتك — كل ذلك باستخدام أوامر اللغة الطبيعية.", + "tools.composio.servers.google-docs.description": "محرر مستندات Google هو معالج نصوص ضمن مجموعة Google Docs المجانية على الويب", + "tools.composio.servers.google-docs.readme": "تكامل مع مستندات Google لإنشاء وتحرير وإدارة المستندات. اكتب المحتوى، ونسّق النص، وتعاون في الوقت الفعلي، وادخل إلى مستنداتك من خلال المحادثة الطبيعية.", + "tools.composio.servers.google-drive.description": "Google Drive هي خدمة تخزين سحابي", + "tools.composio.servers.google-drive.readme": "اتصل بـ Google Drive للوصول إلى ملفاتك وتنظيمها وإدارتها. ابحث في المستندات، وحمّل الملفات، وشارك المحتوى، وتصفح التخزين السحابي بكفاءة بمساعدة الذكاء الاصطناعي.", + "tools.composio.servers.google-sheets.description": "جداول بيانات Google هي تطبيق جداول بيانات عبر الإنترنت يتيح للمستخدمين إنشاء وتحرير والتعاون في الجداول.", + "tools.composio.servers.google-sheets.readme": "اتصل بـ Google Sheets لقراءة وكتابة وتحليل بيانات الجداول. نفّذ الحسابات، وأنشئ التقارير، وارسم المخططات، وأدر البيانات الجدولية بالتعاون مع الذكاء الاصطناعي.", + "tools.composio.servers.hubspot.description": "HubSpot هي شركة تطوير وتسويق برمجيات للتسويق الداخلي والمبيعات وخدمة العملاء", + "tools.composio.servers.hubspot.readme": "تكامل مع HubSpot لإدارة جهات الاتصال، والصفقات، والحملات التسويقية. ادخل إلى بيانات CRM، وتتبع خطوط المبيعات، وأتمت سير العمل، وسهّل عمليات المبيعات والتسويق.", + "tools.composio.servers.jira.description": "Jira هي أداة لإدارة المشاريع وتتبع القضايا طورتها Atlassian", + "tools.composio.servers.jira.readme": "تكامل مع Jira لإدارة المشكلات، وتتبع التقدم، وتنظيم السبرينت. أنشئ التذاكر، وحدث الحالات، واستعلم عن بيانات المشاريع، وسهّل سير عمل التطوير من خلال المحادثة الطبيعية.", + "tools.composio.servers.notion.description": "Notion هو تطبيق إنتاجية وتدوين ملاحظات تعاوني", + "tools.composio.servers.notion.readme": "اتصل بـ Notion للوصول إلى مساحة عملك وإدارتها. أنشئ الصفحات، وابحث في المحتوى، وحدث قواعد البيانات، ونظّم قاعدة معرفتك — كل ذلك من خلال محادثة طبيعية مع مساعدك الذكي.", + "tools.composio.servers.onedrive.description": "OneDrive هي خدمة استضافة ومزامنة ملفات تديرها Microsoft", + "tools.composio.servers.onedrive.readme": "اتصل بـ OneDrive للوصول إلى ملفاتك السحابية من Microsoft وإدارتها. حمّل، ونزّل، وشارك الملفات، ونظّم المجلدات، وتعاون في المستندات بمساعدة الذكاء الاصطناعي.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail هي مجموعة خدمات بريد إلكتروني وجهات اتصال ومهام وتقويم عبر الإنترنت من Microsoft.", + "tools.composio.servers.outlook-mail.readme": "تكامل مع بريد Outlook لقراءة وإرسال وإدارة رسائل البريد الإلكتروني من Microsoft. ابحث في الرسائل، واكتب الرسائل، وأدر المجلدات، ونظّم صندوق الوارد من خلال المحادثة الطبيعية.", + "tools.composio.servers.salesforce.description": "Salesforce هي المنصة الرائدة عالميًا لإدارة علاقات العملاء (CRM) التي تساعد الشركات على التواصل مع العملاء والشركاء والعملاء المحتملين", + "tools.composio.servers.salesforce.readme": "اتصل بـ Salesforce لإدارة علاقات العملاء وبيانات المبيعات. استعلم عن السجلات، وحدث الفرص، وتتبع العملاء المحتملين، وأتمت سير عمل CRM باستخدام أوامر اللغة الطبيعية.", + "tools.composio.servers.slack.description": "Slack هو تطبيق مراسلة للأعمال يربط الأشخاص بالمعلومات التي يحتاجونها", + "tools.composio.servers.slack.readme": "تكامل مع Slack لإرسال الرسائل، والبحث في المحادثات، وإدارة القنوات. تواصل مع فريقك، وأتمت سير العمل في التواصل، وادخل إلى معلومات مساحة العمل من خلال اللغة الطبيعية.", + "tools.composio.servers.supabase.description": "خادم Supabase MCP الرسمي", + "tools.composio.servers.supabase.readme": "تكامل مع Supabase لإدارة قاعدة البيانات وخدمات الخلفية. استعلم عن البيانات، وأدر المصادقة، وتعامل مع التخزين، وتفاعل مع خلفية تطبيقك من خلال المحادثة الطبيعية.", + "tools.composio.servers.whatsapp.description": "تكامل مع واجهة WhatsApp Business API لإرسال الرسائل النصية والوسائط وإدارة المحادثات مع العملاء. مثالي لدعم العملاء، حملات التسويق، وسير العمل الآلي للرسائل من خلال منصة WhatsApp الرسمية.", + "tools.composio.servers.whatsapp.readme": "تكامل مع WhatsApp Business لإرسال الرسائل، وإدارة المحادثات، والتفاعل مع العملاء. أتمت سير العمل في المراسلة وتعامل مع الاتصالات من خلال الذكاء الاصطناعي الحواري.", + "tools.composio.servers.youtube.description": "YouTube هي منصة لمشاركة الفيديوهات حيث يمكن للمستخدمين رفع، مشاركة، واكتشاف المحتوى. الوصول إلى معلومات الفيديو، النصوص، والبيانات الوصفية برمجيًا.", + "tools.composio.servers.youtube.readme": "اتصل بـ YouTube للبحث عن الفيديوهات، والوصول إلى النصوص، واسترجاع معلومات الفيديو. حلل المحتوى، واستخرج البيانات الوصفية، واكتشف الفيديوهات من خلال المحادثة الطبيعية.", + "tools.composio.servers.zendesk.description": "Zendesk هي شركة برمجيات لخدمة العملاء", + "tools.composio.servers.zendesk.readme": "تكامل مع Zendesk لإدارة تذاكر الدعم وتفاعلات العملاء. أنشئ الطلبات، وحدثها، وتتبعها، وادخل إلى بيانات العملاء، وسهّل عمليات الدعم.", + "tools.composio.tools": "الأدوات", + "tools.composio.verifyAuth": "لقد أكملت التحقق", "tools.lobehubSkill.authorize": "تفويض", "tools.lobehubSkill.connect": "اتصال", "tools.lobehubSkill.connected": "متصل", diff --git a/locales/bg-BG/setting.json b/locales/bg-BG/setting.json index acadc4c013d..b4c9755e3bf 100644 --- a/locales/bg-BG/setting.json +++ b/locales/bg-BG/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Деинсталиране на {{name}}", "tools.builtins.uninstalled": "Деинсталирано", "tools.disabled": "Текущият модел не поддържа извикване на функции и не може да използва умението", - "tools.klavis.addServer": "Добави сървър", - "tools.klavis.authCompleted": "Удостоверяването е завършено", - "tools.klavis.authFailed": "Удостоверяването не бе успешно", - "tools.klavis.authRequired": "Изисква се удостоверяване", - "tools.klavis.connect": "Свързване", - "tools.klavis.connected": "Свързан", - "tools.klavis.disconnect": "Прекъсни връзката", - "tools.klavis.disconnected": "Изключено", - "tools.klavis.error": "Грешка", - "tools.klavis.groupName": "Klavis инструменти", - "tools.klavis.manage": "Управление на Klavis", - "tools.klavis.manageTitle": "Управление на интеграция с Klavis", - "tools.klavis.noServers": "Няма свързани сървъри", - "tools.klavis.notEnabled": "Услугата Klavis не е активирана", - "tools.klavis.oauthRequired": "Моля, завършете OAuth удостоверяването в нов прозорец", - "tools.klavis.pendingAuth": "Изчаква удостоверяване", - "tools.klavis.remove": "Премахни", - "tools.klavis.removeConfirm.desc": "{{name}} ще бъде окончателно премахнат от вашите свързани услуги. Това действие не може да бъде отменено.", - "tools.klavis.removeConfirm.title": "Премахване на {{name}}?", - "tools.klavis.serverCreated": "Сървърът е създаден успешно", - "tools.klavis.serverCreatedFailed": "Неуспешно създаване на сървър", - "tools.klavis.serverRemoved": "Сървърът е премахнат", - "tools.klavis.servers": "сървъри", - "tools.klavis.servers.airtable.description": "Airtable е облачна платформа за бази данни и електронни таблици, която съчетава гъвкавостта на таблица с мощта на база данни, позволявайки на екипите да организират, проследяват и сътрудничат по проекти с персонализирани изгледи и мощни функции за автоматизация", - "tools.klavis.servers.airtable.readme": "Интегрирайте се с Airtable за управление на бази данни и работни процеси. Извличайте записи, създавайте нови, актуализирайте данни и автоматизирайте операции с персонализирани изгледи и мощни функции за проследяване.", - "tools.klavis.servers.cal-com.description": "Cal.com е платформа с отворен код за планиране на срещи, която ви помага да организирате срещи без излишна кореспонденция. Управлявайте типове събития, резервации, наличност и интегрирайте с календари за безпроблемно насрочване", - "tools.klavis.servers.cal-com.readme": "Свържете се с Cal.com за управление на графика и срещите си. Преглеждайте наличност, резервирайте срещи, управлявайте типове събития и автоматизирайте календара си чрез естествен разговор.", - "tools.klavis.servers.clickup.description": "ClickUp е цялостна платформа за управление на проекти и продуктивност, която помага на екипите да организират задачи, управляват проекти и сътрудничат ефективно с персонализирани работни процеси и мощни функции за проследяване", - "tools.klavis.servers.clickup.readme": "Свържете се с ClickUp за управление на задачи, проследяване на проекти и организиране на работата си. Създавайте задачи, актуализирайте статуси, управлявайте персонализирани работни процеси и работете в екип чрез естествени езикови команди.", - "tools.klavis.servers.confluence.description": "Confluence е работно пространство за екипи, където знанието и сътрудничеството се срещат", - "tools.klavis.servers.confluence.readme": "Свържете се с Confluence за достъп и управление на екипна документация. Търсете страници, създавайте съдържание, организирайте пространства и изграждайте база знания с помощта на разговорен AI.", - "tools.klavis.servers.dropbox.description": "Цялостно решение за управление на файлове в облачното хранилище Dropbox. Качвайте, изтегляйте, организирайте файлове и папки, управлявайте споделяне и сътрудничество, обработвайте версии на файлове, създавайте заявки за файлове и извършвайте групови операции", - "tools.klavis.servers.dropbox.readme": "Интегрирайте се с Dropbox за достъп и управление на вашите файлове. Качвайте, изтегляйте, споделяйте файлове, управлявайте папки, обработвайте версии и организирайте облачното си хранилище чрез разговорен AI.", - "tools.klavis.servers.figma.description": "Figma е инструмент за съвместен дизайн на интерфейси за уеб и мобилни приложения.", - "tools.klavis.servers.figma.readme": "Свържете се с Figma за достъп до дизайнерски файлове и съвместна работа по проекти. Преглеждайте дизайни, експортирайте ресурси, разглеждайте компоненти и управлявайте дизайнерския си процес чрез естествен разговор.", - "tools.klavis.servers.github.description": "Подобрен MCP сървър за GitHub", - "tools.klavis.servers.github.readme": "Свържете се с GitHub за управление на хранилища, проблеми, pull заявки и код. Търсете код, преглеждайте промени, създавайте клонове и сътрудничете по софтуерни проекти чрез разговорен AI.", - "tools.klavis.servers.gmail.description": "Gmail е безплатна имейл услуга, предоставена от Google", - "tools.klavis.servers.gmail.readme": "Използвайте възможностите на Gmail директно чрез вашия AI асистент. Четете, създавайте и изпращайте имейли, търсете в пощата си, управлявайте етикети и организирайте комуникацията си — всичко това чрез естествен разговор.", - "tools.klavis.servers.google-calendar.description": "Google Calendar е услуга за управление на време и планиране", - "tools.klavis.servers.google-calendar.readme": "Интегрирайте Google Calendar за лесно преглеждане, създаване и управление на събития. Насрочвайте срещи, задавайте напомняния, проверявайте наличност и координирайте времето си чрез естествени езикови команди.", - "tools.klavis.servers.google-docs.description": "Google Docs е текстов редактор, част от безплатния уеб-базиран пакет Google Docs Editors", - "tools.klavis.servers.google-docs.readme": "Интегрирайте се с Google Docs за създаване, редактиране и управление на документи. Пишете съдържание, форматирайте текст, сътрудничете в реално време и достъпвайте документите си чрез естествен разговор.", - "tools.klavis.servers.google-drive.description": "Google Drive е услуга за облачно съхранение", - "tools.klavis.servers.google-drive.readme": "Свържете се с Google Drive за достъп, организиране и управление на файловете си. Търсете документи, качвайте файлове, споделяйте съдържание и навигирайте в облачното си хранилище ефективно с помощта на AI.", - "tools.klavis.servers.google-sheets.description": "Google Sheets е уеб-базирано приложение за електронни таблици, което позволява създаване, редактиране и съвместна работа онлайн", - "tools.klavis.servers.google-sheets.readme": "Свържете се с Google Sheets за четене, писане и анализ на таблични данни. Извършвайте изчисления, генерирайте отчети, създавайте диаграми и управлявайте данни съвместно с помощта на AI.", - "tools.klavis.servers.hubspot.description": "HubSpot е разработчик и доставчик на софтуер за входящ маркетинг, продажби и обслужване на клиенти", - "tools.klavis.servers.hubspot.readme": "Интегрирайте се с HubSpot за управление на контакти, сделки и маркетингови кампании. Достъпвайте CRM данни, следете процеси, автоматизирайте работни потоци и оптимизирайте продажбите и маркетинга си.", - "tools.klavis.servers.jira.description": "Jira е инструмент за управление на проекти и проследяване на проблеми, разработен от Atlassian", - "tools.klavis.servers.jira.readme": "Интегрирайте се с Jira за управление на задачи, проследяване на напредък и организиране на спринтове. Създавайте тикети, актуализирайте статуси, извличайте проектни данни и оптимизирайте работния си процес чрез естествен разговор.", - "tools.klavis.servers.notion.description": "Notion е приложение за продуктивност и водене на бележки със съвместна работа", - "tools.klavis.servers.notion.readme": "Свържете се с Notion за достъп и управление на вашето работно пространство. Създавайте страници, търсете съдържание, актуализирайте бази данни и организирайте базата си знания чрез разговор с вашия AI асистент.", - "tools.klavis.servers.onedrive.description": "OneDrive е услуга за хостинг и синхронизация на файлове, управлявана от Microsoft", - "tools.klavis.servers.onedrive.readme": "Свържете се с OneDrive за достъп и управление на вашите файлове в Microsoft облака. Качвайте, изтегляйте, споделяйте файлове, организирайте папки и сътрудничете по документи с помощта на AI.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail е уеб-базиран пакет от услуги за електронна поща, контакти, задачи и календар от Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Интегрирайте се с Outlook Mail за четене, изпращане и управление на вашите имейли в Microsoft. Търсете съобщения, създавайте имейли, управлявайте папки и организирайте входящата си поща чрез естествен разговор.", - "tools.klavis.servers.salesforce.description": "Salesforce е водещата в света платформа за управление на взаимоотношения с клиенти (CRM), която помага на бизнеса да се свързва с клиенти, партньори и потенциални клиенти", - "tools.klavis.servers.salesforce.readme": "Свържете се със Salesforce за управление на взаимоотношения с клиенти и търговски данни. Извличайте записи, актуализирайте възможности, следете потенциални клиенти и автоматизирайте CRM процесите си чрез естествени езикови команди.", - "tools.klavis.servers.slack.description": "Slack е приложение за бизнес съобщения, което свързва хората с необходимата им информация", - "tools.klavis.servers.slack.readme": "Интегрирайте се със Slack за изпращане на съобщения, търсене в разговори и управление на канали. Свържете се с екипа си, автоматизирайте комуникационни процеси и достъпвайте информация за работното пространство чрез естествен език.", - "tools.klavis.servers.supabase.description": "Официален MCP сървър за Supabase", - "tools.klavis.servers.supabase.readme": "Интегрирайте се със Supabase за управление на бази данни и бекенд услуги. Извличайте данни, управлявайте автентикация, обработвайте хранилище и взаимодействате с бекенда на приложението си чрез естествен разговор.", - "tools.klavis.servers.whatsapp.description": "Интеграция с WhatsApp Business API, която позволява изпращане на текстови съобщения, медия и управление на разговори с клиенти. Идеално за клиентска поддръжка, маркетингови кампании и автоматизирани съобщения чрез официалната платформа на WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Интегрирайте се с WhatsApp Business за изпращане на съобщения, управление на разговори и взаимодействие с клиенти. Автоматизирайте комуникационни процеси и управлявайте съобщенията си чрез разговорен AI.", - "tools.klavis.servers.youtube.description": "YouTube е платформа за споделяне на видеа, където потребителите могат да качват, споделят и откриват съдържание. Достъпвайте информация за видеа, транскрипции и метаданни програмно.", - "tools.klavis.servers.youtube.readme": "Свържете се с YouTube за търсене на видеа, достъп до транскрипции и извличане на информация за видеоклипове. Анализирайте съдържание, извличайте метаданни и откривайте видеа чрез естествен разговор.", - "tools.klavis.servers.zendesk.description": "Zendesk е компания за софтуер за обслужване на клиенти", - "tools.klavis.servers.zendesk.readme": "Интегрирайте се със Zendesk за управление на клиентски запитвания и поддръжка. Създавайте, актуализирайте и проследявайте тикети, достъпвайте клиентски данни и оптимизирайте обслужването си.", - "tools.klavis.tools": "инструменти", - "tools.klavis.verifyAuth": "Завърших удостоверяването", + "tools.composio.addServer": "Добави сървър", + "tools.composio.authCompleted": "Удостоверяването е завършено", + "tools.composio.authFailed": "Удостоверяването не бе успешно", + "tools.composio.authRequired": "Изисква се удостоверяване", + "tools.composio.connect": "Свързване", + "tools.composio.connected": "Свързан", + "tools.composio.disconnect": "Прекъсни връзката", + "tools.composio.disconnected": "Изключено", + "tools.composio.error": "Грешка", + "tools.composio.groupName": "Composio инструменти", + "tools.composio.manage": "Управление на Composio", + "tools.composio.manageTitle": "Управление на интеграция с Composio", + "tools.composio.noServers": "Няма свързани сървъри", + "tools.composio.notEnabled": "Услугата Composio не е активирана", + "tools.composio.oauthRequired": "Моля, завършете OAuth удостоверяването в нов прозорец", + "tools.composio.pendingAuth": "Изчаква удостоверяване", + "tools.composio.serverCreated": "Сървърът е създаден успешно", + "tools.composio.serverCreatedFailed": "Неуспешно създаване на сървър", + "tools.composio.serverRemoved": "Сървърът е премахнат", + "tools.composio.servers": "сървъри", + "tools.composio.servers.airtable.description": "Airtable е облачна платформа за бази данни и електронни таблици, която съчетава гъвкавостта на таблица с мощта на база данни, позволявайки на екипите да организират, проследяват и сътрудничат по проекти с персонализирани изгледи и мощни функции за автоматизация", + "tools.composio.servers.airtable.readme": "Интегрирайте се с Airtable за управление на бази данни и работни процеси. Извличайте записи, създавайте нови, актуализирайте данни и автоматизирайте операции с персонализирани изгледи и мощни функции за проследяване.", + "tools.composio.servers.cal-com.description": "Cal.com е платформа с отворен код за планиране на срещи, която ви помага да организирате срещи без излишна кореспонденция. Управлявайте типове събития, резервации, наличност и интегрирайте с календари за безпроблемно насрочване", + "tools.composio.servers.cal-com.readme": "Свържете се с Cal.com за управление на графика и срещите си. Преглеждайте наличност, резервирайте срещи, управлявайте типове събития и автоматизирайте календара си чрез естествен разговор.", + "tools.composio.servers.clickup.description": "ClickUp е цялостна платформа за управление на проекти и продуктивност, която помага на екипите да организират задачи, управляват проекти и сътрудничат ефективно с персонализирани работни процеси и мощни функции за проследяване", + "tools.composio.servers.clickup.readme": "Свържете се с ClickUp за управление на задачи, проследяване на проекти и организиране на работата си. Създавайте задачи, актуализирайте статуси, управлявайте персонализирани работни процеси и работете в екип чрез естествени езикови команди.", + "tools.composio.servers.confluence.description": "Confluence е работно пространство за екипи, където знанието и сътрудничеството се срещат", + "tools.composio.servers.confluence.readme": "Свържете се с Confluence за достъп и управление на екипна документация. Търсете страници, създавайте съдържание, организирайте пространства и изграждайте база знания с помощта на разговорен AI.", + "tools.composio.servers.dropbox.description": "Цялостно решение за управление на файлове в облачното хранилище Dropbox. Качвайте, изтегляйте, организирайте файлове и папки, управлявайте споделяне и сътрудничество, обработвайте версии на файлове, създавайте заявки за файлове и извършвайте групови операции", + "tools.composio.servers.dropbox.readme": "Интегрирайте се с Dropbox за достъп и управление на вашите файлове. Качвайте, изтегляйте, споделяйте файлове, управлявайте папки, обработвайте версии и организирайте облачното си хранилище чрез разговорен AI.", + "tools.composio.servers.figma.description": "Figma е инструмент за съвместен дизайн на интерфейси за уеб и мобилни приложения.", + "tools.composio.servers.figma.readme": "Свържете се с Figma за достъп до дизайнерски файлове и съвместна работа по проекти. Преглеждайте дизайни, експортирайте ресурси, разглеждайте компоненти и управлявайте дизайнерския си процес чрез естествен разговор.", + "tools.composio.servers.github.description": "Подобрен MCP сървър за GitHub", + "tools.composio.servers.github.readme": "Свържете се с GitHub за управление на хранилища, проблеми, pull заявки и код. Търсете код, преглеждайте промени, създавайте клонове и сътрудничете по софтуерни проекти чрез разговорен AI.", + "tools.composio.servers.gmail.description": "Gmail е безплатна имейл услуга, предоставена от Google", + "tools.composio.servers.gmail.readme": "Използвайте възможностите на Gmail директно чрез вашия AI асистент. Четете, създавайте и изпращайте имейли, търсете в пощата си, управлявайте етикети и организирайте комуникацията си — всичко това чрез естествен разговор.", + "tools.composio.servers.google-calendar.description": "Google Calendar е услуга за управление на време и планиране", + "tools.composio.servers.google-calendar.readme": "Интегрирайте Google Calendar за лесно преглеждане, създаване и управление на събития. Насрочвайте срещи, задавайте напомняния, проверявайте наличност и координирайте времето си чрез естествени езикови команди.", + "tools.composio.servers.google-docs.description": "Google Docs е текстов редактор, част от безплатния уеб-базиран пакет Google Docs Editors", + "tools.composio.servers.google-docs.readme": "Интегрирайте се с Google Docs за създаване, редактиране и управление на документи. Пишете съдържание, форматирайте текст, сътрудничете в реално време и достъпвайте документите си чрез естествен разговор.", + "tools.composio.servers.google-drive.description": "Google Drive е услуга за облачно съхранение", + "tools.composio.servers.google-drive.readme": "Свържете се с Google Drive за достъп, организиране и управление на файловете си. Търсете документи, качвайте файлове, споделяйте съдържание и навигирайте в облачното си хранилище ефективно с помощта на AI.", + "tools.composio.servers.google-sheets.description": "Google Sheets е уеб-базирано приложение за електронни таблици, което позволява създаване, редактиране и съвместна работа онлайн", + "tools.composio.servers.google-sheets.readme": "Свържете се с Google Sheets за четене, писане и анализ на таблични данни. Извършвайте изчисления, генерирайте отчети, създавайте диаграми и управлявайте данни съвместно с помощта на AI.", + "tools.composio.servers.hubspot.description": "HubSpot е разработчик и доставчик на софтуер за входящ маркетинг, продажби и обслужване на клиенти", + "tools.composio.servers.hubspot.readme": "Интегрирайте се с HubSpot за управление на контакти, сделки и маркетингови кампании. Достъпвайте CRM данни, следете процеси, автоматизирайте работни потоци и оптимизирайте продажбите и маркетинга си.", + "tools.composio.servers.jira.description": "Jira е инструмент за управление на проекти и проследяване на проблеми, разработен от Atlassian", + "tools.composio.servers.jira.readme": "Интегрирайте се с Jira за управление на задачи, проследяване на напредък и организиране на спринтове. Създавайте тикети, актуализирайте статуси, извличайте проектни данни и оптимизирайте работния си процес чрез естествен разговор.", + "tools.composio.servers.notion.description": "Notion е приложение за продуктивност и водене на бележки със съвместна работа", + "tools.composio.servers.notion.readme": "Свържете се с Notion за достъп и управление на вашето работно пространство. Създавайте страници, търсете съдържание, актуализирайте бази данни и организирайте базата си знания чрез разговор с вашия AI асистент.", + "tools.composio.servers.onedrive.description": "OneDrive е услуга за хостинг и синхронизация на файлове, управлявана от Microsoft", + "tools.composio.servers.onedrive.readme": "Свържете се с OneDrive за достъп и управление на вашите файлове в Microsoft облака. Качвайте, изтегляйте, споделяйте файлове, организирайте папки и сътрудничете по документи с помощта на AI.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail е уеб-базиран пакет от услуги за електронна поща, контакти, задачи и календар от Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Интегрирайте се с Outlook Mail за четене, изпращане и управление на вашите имейли в Microsoft. Търсете съобщения, създавайте имейли, управлявайте папки и организирайте входящата си поща чрез естествен разговор.", + "tools.composio.servers.salesforce.description": "Salesforce е водещата в света платформа за управление на взаимоотношения с клиенти (CRM), която помага на бизнеса да се свързва с клиенти, партньори и потенциални клиенти", + "tools.composio.servers.salesforce.readme": "Свържете се със Salesforce за управление на взаимоотношения с клиенти и търговски данни. Извличайте записи, актуализирайте възможности, следете потенциални клиенти и автоматизирайте CRM процесите си чрез естествени езикови команди.", + "tools.composio.servers.slack.description": "Slack е приложение за бизнес съобщения, което свързва хората с необходимата им информация", + "tools.composio.servers.slack.readme": "Интегрирайте се със Slack за изпращане на съобщения, търсене в разговори и управление на канали. Свържете се с екипа си, автоматизирайте комуникационни процеси и достъпвайте информация за работното пространство чрез естествен език.", + "tools.composio.servers.supabase.description": "Официален MCP сървър за Supabase", + "tools.composio.servers.supabase.readme": "Интегрирайте се със Supabase за управление на бази данни и бекенд услуги. Извличайте данни, управлявайте автентикация, обработвайте хранилище и взаимодействате с бекенда на приложението си чрез естествен разговор.", + "tools.composio.servers.whatsapp.description": "Интеграция с WhatsApp Business API, която позволява изпращане на текстови съобщения, медия и управление на разговори с клиенти. Идеално за клиентска поддръжка, маркетингови кампании и автоматизирани съобщения чрез официалната платформа на WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Интегрирайте се с WhatsApp Business за изпращане на съобщения, управление на разговори и взаимодействие с клиенти. Автоматизирайте комуникационни процеси и управлявайте съобщенията си чрез разговорен AI.", + "tools.composio.servers.youtube.description": "YouTube е платформа за споделяне на видеа, където потребителите могат да качват, споделят и откриват съдържание. Достъпвайте информация за видеа, транскрипции и метаданни програмно.", + "tools.composio.servers.youtube.readme": "Свържете се с YouTube за търсене на видеа, достъп до транскрипции и извличане на информация за видеоклипове. Анализирайте съдържание, извличайте метаданни и откривайте видеа чрез естествен разговор.", + "tools.composio.servers.zendesk.description": "Zendesk е компания за софтуер за обслужване на клиенти", + "tools.composio.servers.zendesk.readme": "Интегрирайте се със Zendesk за управление на клиентски запитвания и поддръжка. Създавайте, актуализирайте и проследявайте тикети, достъпвайте клиентски данни и оптимизирайте обслужването си.", + "tools.composio.tools": "инструменти", + "tools.composio.verifyAuth": "Завърших удостоверяването", "tools.lobehubSkill.authorize": "Упълномощи", "tools.lobehubSkill.connect": "Свържи", "tools.lobehubSkill.connected": "Свързано", diff --git a/locales/de-DE/setting.json b/locales/de-DE/setting.json index d0a685f5447..fa5bd6199ca 100644 --- a/locales/de-DE/setting.json +++ b/locales/de-DE/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "{{name}} deinstallieren", "tools.builtins.uninstalled": "Deinstalliert", "tools.disabled": "Das aktuelle Modell unterstützt keine Funktionsaufrufe und kann die Fähigkeit nicht nutzen", - "tools.klavis.addServer": "Server hinzufügen", - "tools.klavis.authCompleted": "Authentifizierung abgeschlossen", - "tools.klavis.authFailed": "Authentifizierung fehlgeschlagen", - "tools.klavis.authRequired": "Authentifizierung erforderlich", - "tools.klavis.connect": "Verbinden", - "tools.klavis.connected": "Verbunden", - "tools.klavis.disconnect": "Trennen", - "tools.klavis.disconnected": "Getrennt", - "tools.klavis.error": "Fehler", - "tools.klavis.groupName": "Klavis-Werkzeuge", - "tools.klavis.manage": "Klavis verwalten", - "tools.klavis.manageTitle": "Klavis-Integration verwalten", - "tools.klavis.noServers": "Keine verbundenen Server", - "tools.klavis.notEnabled": "Klavis-Dienst nicht aktiviert", - "tools.klavis.oauthRequired": "Bitte schließen Sie die OAuth-Authentifizierung im neuen Fenster ab", - "tools.klavis.pendingAuth": "Authentifizierung ausstehend", - "tools.klavis.remove": "Entfernen", - "tools.klavis.removeConfirm.desc": "{{name}} wird dauerhaft aus Ihren verbundenen Diensten entfernt. Diese Aktion kann nicht rückgängig gemacht werden.", - "tools.klavis.removeConfirm.title": "{{name}} entfernen?", - "tools.klavis.serverCreated": "Server erfolgreich erstellt", - "tools.klavis.serverCreatedFailed": "Servererstellung fehlgeschlagen", - "tools.klavis.serverRemoved": "Server entfernt", - "tools.klavis.servers": "Server", - "tools.klavis.servers.airtable.description": "Airtable ist eine cloudbasierte Datenbank- und Tabellenplattform, die die Flexibilität einer Tabelle mit der Leistungsfähigkeit einer Datenbank kombiniert. Teams können damit Projekte organisieren, verfolgen und gemeinsam bearbeiten – mit anpassbaren Ansichten und leistungsstarken Automatisierungsfunktionen.", - "tools.klavis.servers.airtable.readme": "Integrieren Sie Airtable, um Ihre Datenbanken und Workflows zu verwalten. Abfragen von Datensätzen, Erstellen von Einträgen, Aktualisieren von Daten und Automatisieren von Abläufen mit anpassbaren Ansichten und leistungsstarken Tracking-Funktionen.", - "tools.klavis.servers.cal-com.description": "Cal.com ist eine Open-Source-Terminplanungsplattform, die es ermöglicht, Meetings ohne lästigen E-Mail-Austausch zu vereinbaren. Verwalten Sie Ereignistypen, Buchungen, Verfügbarkeiten und integrieren Sie Kalender für eine nahtlose Terminplanung.", - "tools.klavis.servers.cal-com.readme": "Verbinden Sie sich mit Cal.com, um Ihre Terminplanung und Verabredungen zu verwalten. Verfügbarkeiten anzeigen, Meetings buchen, Ereignistypen verwalten und Ihren Kalender durch natürliche Konversation automatisieren.", - "tools.klavis.servers.clickup.description": "ClickUp ist eine umfassende Plattform für Projektmanagement und Produktivität, die Teams hilft, Aufgaben zu organisieren, Projekte zu verwalten und effektiv zusammenzuarbeiten – mit anpassbaren Workflows und leistungsstarkem Tracking.", - "tools.klavis.servers.clickup.readme": "Verbinden Sie sich mit ClickUp, um Aufgaben zu verwalten, Projekte zu verfolgen und Ihre Arbeit zu organisieren. Aufgaben erstellen, Status aktualisieren, benutzerdefinierte Workflows verwalten und im Team per natürlicher Sprache zusammenarbeiten.", - "tools.klavis.servers.confluence.description": "Confluence ist ein Teamarbeitsbereich, in dem Wissen und Zusammenarbeit zusammenkommen.", - "tools.klavis.servers.confluence.readme": "Verbinden Sie sich mit Confluence, um auf Teamdokumentationen zuzugreifen und diese zu verwalten. Seiten durchsuchen, Inhalte erstellen, Bereiche organisieren und Ihre Wissensdatenbank mit KI-Unterstützung aufbauen.", - "tools.klavis.servers.dropbox.description": "Umfassende Dateiverwaltungslösung für Dropbox-Cloudspeicher. Dateien und Ordner hochladen, herunterladen, organisieren, Freigaben verwalten, Versionen kontrollieren, Dateianfragen erstellen und Massenoperationen durchführen.", - "tools.klavis.servers.dropbox.readme": "Integrieren Sie Dropbox, um auf Ihre Dateien zuzugreifen und sie zu verwalten. Dateien hochladen, herunterladen, teilen, Ordner verwalten, Dateiversionen handhaben und Ihren Cloud-Speicher per Konversation organisieren.", - "tools.klavis.servers.figma.description": "Figma ist ein kollaboratives Design-Tool für Web- und Mobile-Anwendungen.", - "tools.klavis.servers.figma.readme": "Verbinden Sie sich mit Figma, um auf Design-Dateien zuzugreifen und an Projekten zusammenzuarbeiten. Designs anzeigen, Assets exportieren, Komponenten durchsuchen und Ihren Design-Workflow per natürlicher Sprache verwalten.", - "tools.klavis.servers.github.description": "Erweiterter GitHub-MCP-Server", - "tools.klavis.servers.github.readme": "Verbinden Sie sich mit GitHub, um Repositories, Issues, Pull Requests und Code zu verwalten. Code durchsuchen, Änderungen überprüfen, Branches erstellen und gemeinsam an Softwareprojekten arbeiten – alles per Konversation.", - "tools.klavis.servers.gmail.description": "Gmail ist ein kostenloser E-Mail-Dienst von Google.", - "tools.klavis.servers.gmail.readme": "Nutzen Sie die Funktionen von Gmail direkt in Ihrem KI-Assistenten. E-Mails lesen, verfassen und senden, das Postfach durchsuchen, Labels verwalten und Ihre Kommunikation per natürlicher Sprache organisieren.", - "tools.klavis.servers.google-calendar.description": "Google Kalender ist ein Dienst zur Zeitplanung und Terminverwaltung.", - "tools.klavis.servers.google-calendar.readme": "Integrieren Sie Google Kalender, um Ihre Termine nahtlos anzuzeigen, zu erstellen und zu verwalten. Meetings planen, Erinnerungen setzen, Verfügbarkeiten prüfen und Ihre Zeit per natürlicher Sprache koordinieren.", - "tools.klavis.servers.google-docs.description": "Google Docs ist ein Textverarbeitungsprogramm, das Teil der kostenlosen, webbasierten Google Docs Editors Suite ist.", - "tools.klavis.servers.google-docs.readme": "Integrieren Sie Google Docs, um Dokumente zu erstellen, zu bearbeiten und zu verwalten. Inhalte schreiben, Text formatieren, in Echtzeit zusammenarbeiten und per Konversation auf Ihre Dokumente zugreifen.", - "tools.klavis.servers.google-drive.description": "Google Drive ist ein Cloud-Speicherdienst.", - "tools.klavis.servers.google-drive.readme": "Verbinden Sie sich mit Google Drive, um auf Ihre Dateien zuzugreifen, sie zu organisieren und zu verwalten. Dokumente durchsuchen, Dateien hochladen, Inhalte teilen und Ihren Cloud-Speicher effizient per KI verwalten.", - "tools.klavis.servers.google-sheets.description": "Google Sheets ist eine webbasierte Tabellenkalkulation, mit der Nutzer Tabellen online erstellen, bearbeiten und gemeinsam nutzen können.", - "tools.klavis.servers.google-sheets.readme": "Verbinden Sie sich mit Google Sheets, um Tabellen zu lesen, zu schreiben und zu analysieren. Berechnungen durchführen, Berichte erstellen, Diagramme generieren und tabellarische Daten gemeinsam mit KI verwalten.", - "tools.klavis.servers.hubspot.description": "HubSpot entwickelt Softwareprodukte für Inbound-Marketing, Vertrieb und Kundenservice.", - "tools.klavis.servers.hubspot.readme": "Integrieren Sie HubSpot, um Kontakte, Deals und Marketingkampagnen zu verwalten. Auf CRM-Daten zugreifen, Pipelines verfolgen, Workflows automatisieren und Ihre Vertriebs- und Marketingprozesse optimieren.", - "tools.klavis.servers.jira.description": "Jira ist ein Projektmanagement- und Issue-Tracking-Tool von Atlassian.", - "tools.klavis.servers.jira.readme": "Integrieren Sie Jira, um Issues zu verwalten, Fortschritte zu verfolgen und Sprints zu organisieren. Tickets erstellen, Status aktualisieren, Projektdaten abfragen und Ihren Entwicklungsworkflow per Konversation optimieren.", - "tools.klavis.servers.notion.description": "Notion ist eine kollaborative Produktivitäts- und Notiz-App.", - "tools.klavis.servers.notion.readme": "Verbinden Sie sich mit Notion, um auf Ihren Arbeitsbereich zuzugreifen und ihn zu verwalten. Seiten erstellen, Inhalte durchsuchen, Datenbanken aktualisieren und Ihre Wissensbasis per Konversation organisieren.", - "tools.klavis.servers.onedrive.description": "OneDrive ist ein Datei-Hosting- und Synchronisierungsdienst von Microsoft.", - "tools.klavis.servers.onedrive.readme": "Verbinden Sie sich mit OneDrive, um auf Ihre Microsoft-Cloud-Dateien zuzugreifen und sie zu verwalten. Dateien hochladen, herunterladen, teilen, Ordner organisieren und gemeinsam an Dokumenten arbeiten – mit KI-Unterstützung.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail ist eine webbasierte Suite für E-Mail, Kontakte, Aufgaben und Kalenderdienste von Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Integrieren Sie Outlook Mail, um Ihre Microsoft-E-Mails zu lesen, zu senden und zu verwalten. Nachrichten durchsuchen, E-Mails verfassen, Ordner verwalten und Ihr Postfach per Konversation organisieren.", - "tools.klavis.servers.salesforce.description": "Salesforce ist die weltweit führende CRM-Plattform, die Unternehmen hilft, mit Kunden, Partnern und Interessenten in Kontakt zu treten.", - "tools.klavis.servers.salesforce.readme": "Verbinden Sie sich mit Salesforce, um Kundenbeziehungen und Vertriebsdaten zu verwalten. Datensätze abfragen, Chancen aktualisieren, Leads verfolgen und Ihre CRM-Workflows per natürlicher Sprache automatisieren.", - "tools.klavis.servers.slack.description": "Slack ist eine Business-Messaging-App, die Menschen mit den Informationen verbindet, die sie benötigen.", - "tools.klavis.servers.slack.readme": "Integrieren Sie Slack, um Nachrichten zu senden, Konversationen zu durchsuchen und Kanäle zu verwalten. Mit Ihrem Team kommunizieren, Workflows automatisieren und auf Arbeitsbereichsinformationen per Konversation zugreifen.", - "tools.klavis.servers.supabase.description": "Offizieller Supabase-MCP-Server", - "tools.klavis.servers.supabase.readme": "Integrieren Sie Supabase, um Ihre Datenbank- und Backend-Dienste zu verwalten. Daten abfragen, Authentifizierung verwalten, Speicher organisieren und mit Ihrem Backend per Konversation interagieren.", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API-Integration zum Versenden von Textnachrichten, Medien und zur Verwaltung von Kundengesprächen. Ideal für Kundenservice, Marketingkampagnen und automatisierte Nachrichtenabläufe über die offizielle WhatsApp Business-Plattform.", - "tools.klavis.servers.whatsapp.readme": "Integrieren Sie WhatsApp Business, um Nachrichten zu senden, Konversationen zu verwalten und mit Kunden zu interagieren. Messaging-Workflows automatisieren und Kommunikation per KI steuern.", - "tools.klavis.servers.youtube.description": "YouTube ist eine Video-Plattform, auf der Nutzer Inhalte hochladen, teilen und entdecken können. Greifen Sie programmatisch auf Videoinformationen, Transkripte und Metadaten zu.", - "tools.klavis.servers.youtube.readme": "Verbinden Sie sich mit YouTube, um Videos zu suchen, Transkripte abzurufen und Videoinformationen zu erhalten. Inhalte analysieren, Metadaten extrahieren und Videos per Konversation entdecken.", - "tools.klavis.servers.zendesk.description": "Zendesk ist ein Unternehmen für Kundenservice-Software.", - "tools.klavis.servers.zendesk.readme": "Integrieren Sie Zendesk, um Support-Tickets und Kundeninteraktionen zu verwalten. Anfragen erstellen, aktualisieren und verfolgen, Kundendaten abrufen und Ihre Supportprozesse optimieren.", - "tools.klavis.tools": "Werkzeuge", - "tools.klavis.verifyAuth": "Ich habe die Authentifizierung abgeschlossen", + "tools.composio.addServer": "Server hinzufügen", + "tools.composio.authCompleted": "Authentifizierung abgeschlossen", + "tools.composio.authFailed": "Authentifizierung fehlgeschlagen", + "tools.composio.authRequired": "Authentifizierung erforderlich", + "tools.composio.connect": "Verbinden", + "tools.composio.connected": "Verbunden", + "tools.composio.disconnect": "Trennen", + "tools.composio.disconnected": "Getrennt", + "tools.composio.error": "Fehler", + "tools.composio.groupName": "Composio-Werkzeuge", + "tools.composio.manage": "Composio verwalten", + "tools.composio.manageTitle": "Composio-Integration verwalten", + "tools.composio.noServers": "Keine verbundenen Server", + "tools.composio.notEnabled": "Composio-Dienst nicht aktiviert", + "tools.composio.oauthRequired": "Bitte schließen Sie die OAuth-Authentifizierung im neuen Fenster ab", + "tools.composio.pendingAuth": "Authentifizierung ausstehend", + "tools.composio.serverCreated": "Server erfolgreich erstellt", + "tools.composio.serverCreatedFailed": "Servererstellung fehlgeschlagen", + "tools.composio.serverRemoved": "Server entfernt", + "tools.composio.servers": "Server", + "tools.composio.servers.airtable.description": "Airtable ist eine cloudbasierte Datenbank- und Tabellenplattform, die die Flexibilität einer Tabelle mit der Leistungsfähigkeit einer Datenbank kombiniert. Teams können damit Projekte organisieren, verfolgen und gemeinsam bearbeiten – mit anpassbaren Ansichten und leistungsstarken Automatisierungsfunktionen.", + "tools.composio.servers.airtable.readme": "Integrieren Sie Airtable, um Ihre Datenbanken und Workflows zu verwalten. Abfragen von Datensätzen, Erstellen von Einträgen, Aktualisieren von Daten und Automatisieren von Abläufen mit anpassbaren Ansichten und leistungsstarken Tracking-Funktionen.", + "tools.composio.servers.cal-com.description": "Cal.com ist eine Open-Source-Terminplanungsplattform, die es ermöglicht, Meetings ohne lästigen E-Mail-Austausch zu vereinbaren. Verwalten Sie Ereignistypen, Buchungen, Verfügbarkeiten und integrieren Sie Kalender für eine nahtlose Terminplanung.", + "tools.composio.servers.cal-com.readme": "Verbinden Sie sich mit Cal.com, um Ihre Terminplanung und Verabredungen zu verwalten. Verfügbarkeiten anzeigen, Meetings buchen, Ereignistypen verwalten und Ihren Kalender durch natürliche Konversation automatisieren.", + "tools.composio.servers.clickup.description": "ClickUp ist eine umfassende Plattform für Projektmanagement und Produktivität, die Teams hilft, Aufgaben zu organisieren, Projekte zu verwalten und effektiv zusammenzuarbeiten – mit anpassbaren Workflows und leistungsstarkem Tracking.", + "tools.composio.servers.clickup.readme": "Verbinden Sie sich mit ClickUp, um Aufgaben zu verwalten, Projekte zu verfolgen und Ihre Arbeit zu organisieren. Aufgaben erstellen, Status aktualisieren, benutzerdefinierte Workflows verwalten und im Team per natürlicher Sprache zusammenarbeiten.", + "tools.composio.servers.confluence.description": "Confluence ist ein Teamarbeitsbereich, in dem Wissen und Zusammenarbeit zusammenkommen.", + "tools.composio.servers.confluence.readme": "Verbinden Sie sich mit Confluence, um auf Teamdokumentationen zuzugreifen und diese zu verwalten. Seiten durchsuchen, Inhalte erstellen, Bereiche organisieren und Ihre Wissensdatenbank mit KI-Unterstützung aufbauen.", + "tools.composio.servers.dropbox.description": "Umfassende Dateiverwaltungslösung für Dropbox-Cloudspeicher. Dateien und Ordner hochladen, herunterladen, organisieren, Freigaben verwalten, Versionen kontrollieren, Dateianfragen erstellen und Massenoperationen durchführen.", + "tools.composio.servers.dropbox.readme": "Integrieren Sie Dropbox, um auf Ihre Dateien zuzugreifen und sie zu verwalten. Dateien hochladen, herunterladen, teilen, Ordner verwalten, Dateiversionen handhaben und Ihren Cloud-Speicher per Konversation organisieren.", + "tools.composio.servers.figma.description": "Figma ist ein kollaboratives Design-Tool für Web- und Mobile-Anwendungen.", + "tools.composio.servers.figma.readme": "Verbinden Sie sich mit Figma, um auf Design-Dateien zuzugreifen und an Projekten zusammenzuarbeiten. Designs anzeigen, Assets exportieren, Komponenten durchsuchen und Ihren Design-Workflow per natürlicher Sprache verwalten.", + "tools.composio.servers.github.description": "Erweiterter GitHub-MCP-Server", + "tools.composio.servers.github.readme": "Verbinden Sie sich mit GitHub, um Repositories, Issues, Pull Requests und Code zu verwalten. Code durchsuchen, Änderungen überprüfen, Branches erstellen und gemeinsam an Softwareprojekten arbeiten – alles per Konversation.", + "tools.composio.servers.gmail.description": "Gmail ist ein kostenloser E-Mail-Dienst von Google.", + "tools.composio.servers.gmail.readme": "Nutzen Sie die Funktionen von Gmail direkt in Ihrem KI-Assistenten. E-Mails lesen, verfassen und senden, das Postfach durchsuchen, Labels verwalten und Ihre Kommunikation per natürlicher Sprache organisieren.", + "tools.composio.servers.google-calendar.description": "Google Kalender ist ein Dienst zur Zeitplanung und Terminverwaltung.", + "tools.composio.servers.google-calendar.readme": "Integrieren Sie Google Kalender, um Ihre Termine nahtlos anzuzeigen, zu erstellen und zu verwalten. Meetings planen, Erinnerungen setzen, Verfügbarkeiten prüfen und Ihre Zeit per natürlicher Sprache koordinieren.", + "tools.composio.servers.google-docs.description": "Google Docs ist ein Textverarbeitungsprogramm, das Teil der kostenlosen, webbasierten Google Docs Editors Suite ist.", + "tools.composio.servers.google-docs.readme": "Integrieren Sie Google Docs, um Dokumente zu erstellen, zu bearbeiten und zu verwalten. Inhalte schreiben, Text formatieren, in Echtzeit zusammenarbeiten und per Konversation auf Ihre Dokumente zugreifen.", + "tools.composio.servers.google-drive.description": "Google Drive ist ein Cloud-Speicherdienst.", + "tools.composio.servers.google-drive.readme": "Verbinden Sie sich mit Google Drive, um auf Ihre Dateien zuzugreifen, sie zu organisieren und zu verwalten. Dokumente durchsuchen, Dateien hochladen, Inhalte teilen und Ihren Cloud-Speicher effizient per KI verwalten.", + "tools.composio.servers.google-sheets.description": "Google Sheets ist eine webbasierte Tabellenkalkulation, mit der Nutzer Tabellen online erstellen, bearbeiten und gemeinsam nutzen können.", + "tools.composio.servers.google-sheets.readme": "Verbinden Sie sich mit Google Sheets, um Tabellen zu lesen, zu schreiben und zu analysieren. Berechnungen durchführen, Berichte erstellen, Diagramme generieren und tabellarische Daten gemeinsam mit KI verwalten.", + "tools.composio.servers.hubspot.description": "HubSpot entwickelt Softwareprodukte für Inbound-Marketing, Vertrieb und Kundenservice.", + "tools.composio.servers.hubspot.readme": "Integrieren Sie HubSpot, um Kontakte, Deals und Marketingkampagnen zu verwalten. Auf CRM-Daten zugreifen, Pipelines verfolgen, Workflows automatisieren und Ihre Vertriebs- und Marketingprozesse optimieren.", + "tools.composio.servers.jira.description": "Jira ist ein Projektmanagement- und Issue-Tracking-Tool von Atlassian.", + "tools.composio.servers.jira.readme": "Integrieren Sie Jira, um Issues zu verwalten, Fortschritte zu verfolgen und Sprints zu organisieren. Tickets erstellen, Status aktualisieren, Projektdaten abfragen und Ihren Entwicklungsworkflow per Konversation optimieren.", + "tools.composio.servers.notion.description": "Notion ist eine kollaborative Produktivitäts- und Notiz-App.", + "tools.composio.servers.notion.readme": "Verbinden Sie sich mit Notion, um auf Ihren Arbeitsbereich zuzugreifen und ihn zu verwalten. Seiten erstellen, Inhalte durchsuchen, Datenbanken aktualisieren und Ihre Wissensbasis per Konversation organisieren.", + "tools.composio.servers.onedrive.description": "OneDrive ist ein Datei-Hosting- und Synchronisierungsdienst von Microsoft.", + "tools.composio.servers.onedrive.readme": "Verbinden Sie sich mit OneDrive, um auf Ihre Microsoft-Cloud-Dateien zuzugreifen und sie zu verwalten. Dateien hochladen, herunterladen, teilen, Ordner organisieren und gemeinsam an Dokumenten arbeiten – mit KI-Unterstützung.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail ist eine webbasierte Suite für E-Mail, Kontakte, Aufgaben und Kalenderdienste von Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Integrieren Sie Outlook Mail, um Ihre Microsoft-E-Mails zu lesen, zu senden und zu verwalten. Nachrichten durchsuchen, E-Mails verfassen, Ordner verwalten und Ihr Postfach per Konversation organisieren.", + "tools.composio.servers.salesforce.description": "Salesforce ist die weltweit führende CRM-Plattform, die Unternehmen hilft, mit Kunden, Partnern und Interessenten in Kontakt zu treten.", + "tools.composio.servers.salesforce.readme": "Verbinden Sie sich mit Salesforce, um Kundenbeziehungen und Vertriebsdaten zu verwalten. Datensätze abfragen, Chancen aktualisieren, Leads verfolgen und Ihre CRM-Workflows per natürlicher Sprache automatisieren.", + "tools.composio.servers.slack.description": "Slack ist eine Business-Messaging-App, die Menschen mit den Informationen verbindet, die sie benötigen.", + "tools.composio.servers.slack.readme": "Integrieren Sie Slack, um Nachrichten zu senden, Konversationen zu durchsuchen und Kanäle zu verwalten. Mit Ihrem Team kommunizieren, Workflows automatisieren und auf Arbeitsbereichsinformationen per Konversation zugreifen.", + "tools.composio.servers.supabase.description": "Offizieller Supabase-MCP-Server", + "tools.composio.servers.supabase.readme": "Integrieren Sie Supabase, um Ihre Datenbank- und Backend-Dienste zu verwalten. Daten abfragen, Authentifizierung verwalten, Speicher organisieren und mit Ihrem Backend per Konversation interagieren.", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API-Integration zum Versenden von Textnachrichten, Medien und zur Verwaltung von Kundengesprächen. Ideal für Kundenservice, Marketingkampagnen und automatisierte Nachrichtenabläufe über die offizielle WhatsApp Business-Plattform.", + "tools.composio.servers.whatsapp.readme": "Integrieren Sie WhatsApp Business, um Nachrichten zu senden, Konversationen zu verwalten und mit Kunden zu interagieren. Messaging-Workflows automatisieren und Kommunikation per KI steuern.", + "tools.composio.servers.youtube.description": "YouTube ist eine Video-Plattform, auf der Nutzer Inhalte hochladen, teilen und entdecken können. Greifen Sie programmatisch auf Videoinformationen, Transkripte und Metadaten zu.", + "tools.composio.servers.youtube.readme": "Verbinden Sie sich mit YouTube, um Videos zu suchen, Transkripte abzurufen und Videoinformationen zu erhalten. Inhalte analysieren, Metadaten extrahieren und Videos per Konversation entdecken.", + "tools.composio.servers.zendesk.description": "Zendesk ist ein Unternehmen für Kundenservice-Software.", + "tools.composio.servers.zendesk.readme": "Integrieren Sie Zendesk, um Support-Tickets und Kundeninteraktionen zu verwalten. Anfragen erstellen, aktualisieren und verfolgen, Kundendaten abrufen und Ihre Supportprozesse optimieren.", + "tools.composio.tools": "Werkzeuge", + "tools.composio.verifyAuth": "Ich habe die Authentifizierung abgeschlossen", "tools.lobehubSkill.authorize": "Autorisieren", "tools.lobehubSkill.connect": "Verbinden", "tools.lobehubSkill.connected": "Verbunden", diff --git a/locales/en-US/setting.json b/locales/en-US/setting.json index f09db972e47..3facfb067e5 100644 --- a/locales/en-US/setting.json +++ b/locales/en-US/setting.json @@ -1172,77 +1172,78 @@ "tools.builtins.uninstallConfirm.title": "Uninstall {{name}}", "tools.builtins.uninstalled": "Uninstalled", "tools.disabled": "The current model does not support function calls and cannot use the skill", - "tools.klavis.addServer": "Add Server", - "tools.klavis.authCompleted": "Authentication Completed", - "tools.klavis.authFailed": "Authentication Failed", - "tools.klavis.authRequired": "Authentication Required", - "tools.klavis.connect": "Connect", - "tools.klavis.connected": "Connected", - "tools.klavis.disconnect": "Disconnect", - "tools.klavis.disconnected": "Disconnected", - "tools.klavis.error": "Error", - "tools.klavis.groupName": "Klavis Tools", - "tools.klavis.manage": "Manage Klavis", - "tools.klavis.manageTitle": "Manage Klavis Integration", - "tools.klavis.noServers": "No connected servers", - "tools.klavis.notEnabled": "Klavis service not enabled", - "tools.klavis.oauthRequired": "Please complete OAuth authentication in the new window", - "tools.klavis.pendingAuth": "Pending Authentication", - "tools.klavis.remove": "Remove", - "tools.klavis.removeConfirm.desc": "{{name}} will be permanently removed from your connected services. This action cannot be undone.", - "tools.klavis.removeConfirm.title": "Remove {{name}}?", - "tools.klavis.serverCreated": "Server created successfully", - "tools.klavis.serverCreatedFailed": "Failed to create server", - "tools.klavis.serverRemoved": "Server removed", - "tools.klavis.servers": "servers", - "tools.klavis.servers.airtable.description": "Airtable is a cloud-based database and spreadsheet platform that combines the flexibility of a spreadsheet with the power of a database, enabling teams to organize, track, and collaborate on projects with customizable views and powerful automation features", - "tools.klavis.servers.airtable.readme": "Integrate with Airtable to manage your databases and workflows. Query records, create entries, update data, and automate operations with customizable views and powerful tracking features.", - "tools.klavis.servers.cal-com.description": "Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails. Manage event types, bookings, availability, and integrate with calendars for seamless appointment scheduling", - "tools.klavis.servers.cal-com.readme": "Connect to Cal.com to manage your scheduling and appointments. View availability, book meetings, manage event types, and automate your calendar through natural conversation.", - "tools.klavis.servers.clickup.description": "ClickUp is a comprehensive project management and productivity platform that helps teams organize tasks, manage projects, and collaborate effectively with customizable workflows and powerful tracking features", - "tools.klavis.servers.clickup.readme": "Connect to ClickUp to manage tasks, track projects, and organize your work. Create tasks, update statuses, manage custom workflows, and collaborate with your team through natural language commands.", - "tools.klavis.servers.confluence.description": "Confluence is a team workspace where knowledge and collaboration meet", - "tools.klavis.servers.confluence.readme": "Connect to Confluence to access and manage team documentation. Search pages, create content, organize spaces, and build your knowledge base through conversational AI assistance.", - "tools.klavis.servers.dropbox.description": "Complete file management solution for Dropbox cloud storage. Upload, download, organize files and folders, manage sharing and collaboration, handle file versions, create file requests, and perform batch operations on your Dropbox files and folders", - "tools.klavis.servers.dropbox.readme": "Integrate with Dropbox to access and manage your files. Upload, download, share files, manage folders, handle file versions, and organize your cloud storage through conversational AI.", - "tools.klavis.servers.figma.description": "Figma is a collaborative interface design tool for web and mobile applications.", - "tools.klavis.servers.figma.readme": "Connect to Figma to access design files and collaborate on projects. View designs, export assets, browse components, and manage your design workflow through natural conversation.", - "tools.klavis.servers.github.description": "Enhanced GitHub MCP Server", - "tools.klavis.servers.github.readme": "Connect to GitHub to manage repositories, issues, pull requests, and code. Search code, review changes, create branches, and collaborate on software development projects through conversational AI.", - "tools.klavis.servers.gmail.description": "Gmail is a free email service provided by Google", - "tools.klavis.servers.gmail.readme": "Bring the power of Gmail directly into your AI assistant. Read, compose, and send emails, search your inbox, manage labels, and organize your communications—all through natural conversation.", - "tools.klavis.servers.google-calendar.description": "Google Calendar is a time-management and scheduling calendar service", - "tools.klavis.servers.google-calendar.readme": "Integrate Google Calendar to view, create, and manage your events seamlessly. Schedule meetings, set reminders, check availability, and coordinate your time—all through natural language commands.", - "tools.klavis.servers.google-docs.description": "Google Docs is a word processor included as part of the free, web-based Google Docs Editors suite", - "tools.klavis.servers.google-docs.readme": "Integrate with Google Docs to create, edit, and manage documents. Write content, format text, collaborate in real-time, and access your documents through natural conversation.", - "tools.klavis.servers.google-drive.description": "Google Drive is a cloud storage service", - "tools.klavis.servers.google-drive.readme": "Connect to Google Drive to access, organize, and manage your files. Search documents, upload files, share content, and navigate your cloud storage efficiently through AI assistance.", - "tools.klavis.servers.google-sheets.description": "Google Sheets is a web-based spreadsheet application that allows users to create, edit, and collaborate on spreadsheets online", - "tools.klavis.servers.google-sheets.readme": "Connect to Google Sheets to read, write, and analyze spreadsheet data. Perform calculations, generate reports, create charts, and manage tabular data collaboratively with AI assistance.", - "tools.klavis.servers.hubspot.description": "HubSpot is a developer and marketer of software products for inbound marketing, sales, and customer service", - "tools.klavis.servers.hubspot.readme": "Integrate with HubSpot to manage contacts, deals, and marketing campaigns. Access CRM data, track pipelines, automate workflows, and streamline your sales and marketing operations.", - "tools.klavis.servers.jira.description": "Jira is a project management and issue tracking tool developed by Atlassian", - "tools.klavis.servers.jira.readme": "Integrate with Jira to manage issues, track progress, and organize sprints. Create tickets, update statuses, query project data, and streamline your development workflow through natural conversation.", - "tools.klavis.servers.notion.description": "Notion is a collaborative productivity and note-taking application", - "tools.klavis.servers.notion.readme": "Connect to Notion to access and manage your workspace. Create pages, search content, update databases, and organize your knowledge base—all through natural conversation with your AI assistant.", - "tools.klavis.servers.onedrive.description": "OneDrive is a file hosting service and synchronization service operated by Microsoft", - "tools.klavis.servers.onedrive.readme": "Connect to OneDrive to access and manage your Microsoft cloud files. Upload, download, share files, organize folders, and collaborate on documents through AI-powered assistance.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail is a web-based suite of webmail, contacts, tasks, and calendaring services from Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Integrate with Outlook Mail to read, send, and manage your Microsoft emails. Search messages, compose emails, manage folders, and organize your inbox through natural conversation.", - "tools.klavis.servers.salesforce.description": "Salesforce is the world's leading customer relationship management (CRM) platform that helps businesses connect with customers, partners, and potential customers", - "tools.klavis.servers.salesforce.readme": "Connect to Salesforce to manage customer relationships and sales data. Query records, update opportunities, track leads, and automate your CRM workflows through natural language commands.", - "tools.klavis.servers.slack.description": "Slack is a messaging app for business that connects people to the information they need", - "tools.klavis.servers.slack.readme": "Integrate with Slack to send messages, search conversations, and manage channels. Connect with your team, automate communication workflows, and access workspace information through natural language.", - "tools.klavis.servers.supabase.description": "Supabase official MCP Server", - "tools.klavis.servers.supabase.readme": "Integrate with Supabase to manage your database and backend services. Query data, manage authentication, handle storage, and interact with your application backend through natural conversation.", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers. Perfect for customer support, marketing campaigns, and automated messaging workflows through the official WhatsApp Business platform.", - "tools.klavis.servers.whatsapp.readme": "Integrate with WhatsApp Business to send messages, manage conversations, and engage with customers. Automate messaging workflows and handle communications through conversational AI.", - "tools.klavis.servers.youtube.description": "YouTube is a video-sharing platform where users can upload, share, and discover content. Access video information, transcripts, and metadata programmatically.", - "tools.klavis.servers.youtube.readme": "Connect to YouTube to search videos, access transcripts, and retrieve video information. Analyze content, extract metadata, and discover videos through natural conversation.", - "tools.klavis.servers.zendesk.description": "Zendesk is a customer service software company", - "tools.klavis.servers.zendesk.readme": "Integrate with Zendesk to manage support tickets and customer interactions. Create, update, and track support requests, access customer data, and streamline your support operations.", - "tools.klavis.tools": "tools", - "tools.klavis.verifyAuth": "I have completed authentication", + "tools.composio.addServer": "Add Server", + "tools.composio.authCompleted": "Authentication Completed", + "tools.composio.authFailed": "Authentication Failed", + "tools.composio.authRequired": "Authentication Required", + "tools.composio.connect": "Connect", + "tools.composio.connected": "Connected", + "tools.composio.disconnect": "Disconnect", + "tools.composio.disconnected": "Disconnected", + "tools.composio.error": "Error", + "tools.composio.remove": "Remove", + "tools.composio.removeConfirm.desc": "{{name}} will be permanently removed from your connected services. This action cannot be undone.", + "tools.composio.removeConfirm.title": "Remove {{name}}?", + "tools.composio.groupName": "Composio Tools", + "tools.composio.manage": "Manage Composio", + "tools.composio.manageTitle": "Manage Composio Integration", + "tools.composio.noServers": "No connected servers", + "tools.composio.notEnabled": "Composio service not enabled", + "tools.composio.oauthRequired": "Please complete OAuth authentication in the new window", + "tools.composio.pendingAuth": "Pending Authentication", + "tools.composio.reauthorize": "Re-authorize", + "tools.composio.serverCreated": "Server created successfully", + "tools.composio.serverCreatedFailed": "Failed to create server", + "tools.composio.serverRemoved": "Server removed", + "tools.composio.servers": "servers", + "tools.composio.servers.airtable.description": "Airtable is a cloud-based database and spreadsheet platform that combines the flexibility of a spreadsheet with the power of a database, enabling teams to organize, track, and collaborate on projects with customizable views and powerful automation features", + "tools.composio.servers.airtable.readme": "Integrate with Airtable to manage your databases and workflows. Query records, create entries, update data, and automate operations with customizable views and powerful tracking features.", + "tools.composio.servers.cal-com.description": "Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails. Manage event types, bookings, availability, and integrate with calendars for seamless appointment scheduling", + "tools.composio.servers.cal-com.readme": "Connect to Cal.com to manage your scheduling and appointments. View availability, book meetings, manage event types, and automate your calendar through natural conversation.", + "tools.composio.servers.clickup.description": "ClickUp is a comprehensive project management and productivity platform that helps teams organize tasks, manage projects, and collaborate effectively with customizable workflows and powerful tracking features", + "tools.composio.servers.clickup.readme": "Connect to ClickUp to manage tasks, track projects, and organize your work. Create tasks, update statuses, manage custom workflows, and collaborate with your team through natural language commands.", + "tools.composio.servers.confluence.description": "Confluence is a team workspace where knowledge and collaboration meet", + "tools.composio.servers.confluence.readme": "Connect to Confluence to access and manage team documentation. Search pages, create content, organize spaces, and build your knowledge base through conversational AI assistance.", + "tools.composio.servers.dropbox.description": "Complete file management solution for Dropbox cloud storage. Upload, download, organize files and folders, manage sharing and collaboration, handle file versions, create file requests, and perform batch operations on your Dropbox files and folders", + "tools.composio.servers.dropbox.readme": "Integrate with Dropbox to access and manage your files. Upload, download, share files, manage folders, handle file versions, and organize your cloud storage through conversational AI.", + "tools.composio.servers.figma.description": "Figma is a collaborative interface design tool for web and mobile applications.", + "tools.composio.servers.figma.readme": "Connect to Figma to access design files and collaborate on projects. View designs, export assets, browse components, and manage your design workflow through natural conversation.", + "tools.composio.servers.github.description": "Enhanced GitHub MCP Server", + "tools.composio.servers.github.readme": "Connect to GitHub to manage repositories, issues, pull requests, and code. Search code, review changes, create branches, and collaborate on software development projects through conversational AI.", + "tools.composio.servers.gmail.description": "Gmail is a free email service provided by Google", + "tools.composio.servers.gmail.readme": "Bring the power of Gmail directly into your AI assistant. Read, compose, and send emails, search your inbox, manage labels, and organize your communications—all through natural conversation.", + "tools.composio.servers.google-calendar.description": "Google Calendar is a time-management and scheduling calendar service", + "tools.composio.servers.google-calendar.readme": "Integrate Google Calendar to view, create, and manage your events seamlessly. Schedule meetings, set reminders, check availability, and coordinate your time—all through natural language commands.", + "tools.composio.servers.google-docs.description": "Google Docs is a word processor included as part of the free, web-based Google Docs Editors suite", + "tools.composio.servers.google-docs.readme": "Integrate with Google Docs to create, edit, and manage documents. Write content, format text, collaborate in real-time, and access your documents through natural conversation.", + "tools.composio.servers.google-drive.description": "Google Drive is a cloud storage service", + "tools.composio.servers.google-drive.readme": "Connect to Google Drive to access, organize, and manage your files. Search documents, upload files, share content, and navigate your cloud storage efficiently through AI assistance.", + "tools.composio.servers.google-sheets.description": "Google Sheets is a web-based spreadsheet application that allows users to create, edit, and collaborate on spreadsheets online", + "tools.composio.servers.google-sheets.readme": "Connect to Google Sheets to read, write, and analyze spreadsheet data. Perform calculations, generate reports, create charts, and manage tabular data collaboratively with AI assistance.", + "tools.composio.servers.hubspot.description": "HubSpot is a developer and marketer of software products for inbound marketing, sales, and customer service", + "tools.composio.servers.hubspot.readme": "Integrate with HubSpot to manage contacts, deals, and marketing campaigns. Access CRM data, track pipelines, automate workflows, and streamline your sales and marketing operations.", + "tools.composio.servers.jira.description": "Jira is a project management and issue tracking tool developed by Atlassian", + "tools.composio.servers.jira.readme": "Integrate with Jira to manage issues, track progress, and organize sprints. Create tickets, update statuses, query project data, and streamline your development workflow through natural conversation.", + "tools.composio.servers.notion.description": "Notion is a collaborative productivity and note-taking application", + "tools.composio.servers.notion.readme": "Connect to Notion to access and manage your workspace. Create pages, search content, update databases, and organize your knowledge base—all through natural conversation with your AI assistant.", + "tools.composio.servers.onedrive.description": "OneDrive is a file hosting service and synchronization service operated by Microsoft", + "tools.composio.servers.onedrive.readme": "Connect to OneDrive to access and manage your Microsoft cloud files. Upload, download, share files, organize folders, and collaborate on documents through AI-powered assistance.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail is a web-based suite of webmail, contacts, tasks, and calendaring services from Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Integrate with Outlook Mail to read, send, and manage your Microsoft emails. Search messages, compose emails, manage folders, and organize your inbox through natural conversation.", + "tools.composio.servers.salesforce.description": "Salesforce is the world's leading customer relationship management (CRM) platform that helps businesses connect with customers, partners, and potential customers", + "tools.composio.servers.salesforce.readme": "Connect to Salesforce to manage customer relationships and sales data. Query records, update opportunities, track leads, and automate your CRM workflows through natural language commands.", + "tools.composio.servers.slack.description": "Slack is a messaging app for business that connects people to the information they need", + "tools.composio.servers.slack.readme": "Integrate with Slack to send messages, search conversations, and manage channels. Connect with your team, automate communication workflows, and access workspace information through natural language.", + "tools.composio.servers.supabase.description": "Supabase official MCP Server", + "tools.composio.servers.supabase.readme": "Integrate with Supabase to manage your database and backend services. Query data, manage authentication, handle storage, and interact with your application backend through natural conversation.", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers. Perfect for customer support, marketing campaigns, and automated messaging workflows through the official WhatsApp Business platform.", + "tools.composio.servers.whatsapp.readme": "Integrate with WhatsApp Business to send messages, manage conversations, and engage with customers. Automate messaging workflows and handle communications through conversational AI.", + "tools.composio.servers.youtube.description": "YouTube is a video-sharing platform where users can upload, share, and discover content. Access video information, transcripts, and metadata programmatically.", + "tools.composio.servers.youtube.readme": "Connect to YouTube to search videos, access transcripts, and retrieve video information. Analyze content, extract metadata, and discover videos through natural conversation.", + "tools.composio.servers.zendesk.description": "Zendesk is a customer service software company", + "tools.composio.servers.zendesk.readme": "Integrate with Zendesk to manage support tickets and customer interactions. Create, update, and track support requests, access customer data, and streamline your support operations.", + "tools.composio.tools": "tools", + "tools.composio.verifyAuth": "I have completed authentication", "tools.lobehubSkill.authorize": "Authorize", "tools.lobehubSkill.connect": "Connect", "tools.lobehubSkill.connected": "Connected", diff --git a/locales/es-ES/setting.json b/locales/es-ES/setting.json index 3417e1d6455..1d18f378991 100644 --- a/locales/es-ES/setting.json +++ b/locales/es-ES/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Desinstalar {{name}}", "tools.builtins.uninstalled": "Desinstalado", "tools.disabled": "El modelo actual no admite llamadas a funciones y no puede usar esta habilidad", - "tools.klavis.addServer": "Agregar Servidor", - "tools.klavis.authCompleted": "Autenticación Completada", - "tools.klavis.authFailed": "Autenticación Fallida", - "tools.klavis.authRequired": "Autenticación Requerida", - "tools.klavis.connect": "Conectar", - "tools.klavis.connected": "Conectado", - "tools.klavis.disconnect": "Desconectar", - "tools.klavis.disconnected": "Desconectado", - "tools.klavis.error": "Error", - "tools.klavis.groupName": "Herramientas Klavis", - "tools.klavis.manage": "Gestionar Klavis", - "tools.klavis.manageTitle": "Gestionar Integración de Klavis", - "tools.klavis.noServers": "No hay servidores conectados", - "tools.klavis.notEnabled": "Servicio Klavis no habilitado", - "tools.klavis.oauthRequired": "Por favor, completa la autenticación OAuth en la nueva ventana", - "tools.klavis.pendingAuth": "Autenticación Pendiente", - "tools.klavis.remove": "Eliminar", - "tools.klavis.removeConfirm.desc": "{{name}} se eliminará permanentemente de tus servicios conectados. Esta acción no se puede deshacer.", - "tools.klavis.removeConfirm.title": "¿Eliminar {{name}}?", - "tools.klavis.serverCreated": "Servidor creado con éxito", - "tools.klavis.serverCreatedFailed": "Error al crear el servidor", - "tools.klavis.serverRemoved": "Servidor eliminado", - "tools.klavis.servers": "servidores", - "tools.klavis.servers.airtable.description": "Airtable es una plataforma en la nube que combina la flexibilidad de una hoja de cálculo con el poder de una base de datos, permitiendo a los equipos organizar, seguir y colaborar en proyectos con vistas personalizables y potentes funciones de automatización.", - "tools.klavis.servers.airtable.readme": "Integra con Airtable para gestionar tus bases de datos y flujos de trabajo. Consulta registros, crea entradas, actualiza datos y automatiza operaciones con vistas personalizables y potentes funciones de seguimiento.", - "tools.klavis.servers.cal-com.description": "Cal.com es una plataforma de programación de código abierto que te ayuda a agendar reuniones sin correos electrónicos innecesarios. Administra tipos de eventos, reservas, disponibilidad e intégralo con calendarios para una programación fluida.", - "tools.klavis.servers.cal-com.readme": "Conéctate con Cal.com para gestionar tu agenda y citas. Consulta disponibilidad, programa reuniones, gestiona tipos de eventos y automatiza tu calendario mediante conversación natural.", - "tools.klavis.servers.clickup.description": "ClickUp es una plataforma integral de gestión de proyectos y productividad que ayuda a los equipos a organizar tareas, gestionar proyectos y colaborar eficazmente con flujos de trabajo personalizables y potentes funciones de seguimiento.", - "tools.klavis.servers.clickup.readme": "Conéctate con ClickUp para gestionar tareas, seguir proyectos y organizar tu trabajo. Crea tareas, actualiza estados, gestiona flujos de trabajo personalizados y colabora con tu equipo mediante comandos en lenguaje natural.", - "tools.klavis.servers.confluence.description": "Confluence es un espacio de trabajo en equipo donde se combinan el conocimiento y la colaboración.", - "tools.klavis.servers.confluence.readme": "Conéctate con Confluence para acceder y gestionar la documentación del equipo. Busca páginas, crea contenido, organiza espacios y construye tu base de conocimiento con ayuda de IA conversacional.", - "tools.klavis.servers.dropbox.description": "Solución completa de gestión de archivos para el almacenamiento en la nube de Dropbox. Sube, descarga, organiza archivos y carpetas, gestiona el uso compartido y la colaboración, maneja versiones de archivos, crea solicitudes de archivos y realiza operaciones por lotes en tus archivos y carpetas de Dropbox.", - "tools.klavis.servers.dropbox.readme": "Integra con Dropbox para acceder y gestionar tus archivos. Sube, descarga, comparte archivos, organiza carpetas, gestiona versiones y administra tu almacenamiento en la nube mediante IA conversacional.", - "tools.klavis.servers.figma.description": "Figma es una herramienta colaborativa de diseño de interfaces para aplicaciones web y móviles.", - "tools.klavis.servers.figma.readme": "Conéctate con Figma para acceder a archivos de diseño y colaborar en proyectos. Visualiza diseños, exporta recursos, explora componentes y gestiona tu flujo de trabajo de diseño mediante conversación natural.", - "tools.klavis.servers.github.description": "Servidor MCP de GitHub mejorado", - "tools.klavis.servers.github.readme": "Conéctate con GitHub para gestionar repositorios, incidencias, pull requests y código. Busca código, revisa cambios, crea ramas y colabora en proyectos de desarrollo de software mediante IA conversacional.", - "tools.klavis.servers.gmail.description": "Gmail es un servicio de correo electrónico gratuito proporcionado por Google", - "tools.klavis.servers.gmail.readme": "Lleva el poder de Gmail directamente a tu asistente de IA. Lee, redacta y envía correos, busca en tu bandeja de entrada, gestiona etiquetas y organiza tus comunicaciones, todo mediante conversación natural.", - "tools.klavis.servers.google-calendar.description": "Google Calendar es un servicio de calendario para la gestión del tiempo y programación de eventos", - "tools.klavis.servers.google-calendar.readme": "Integra Google Calendar para ver, crear y gestionar tus eventos sin complicaciones. Programa reuniones, establece recordatorios, consulta disponibilidad y organiza tu tiempo mediante comandos en lenguaje natural.", - "tools.klavis.servers.google-docs.description": "Google Docs es un procesador de texto incluido en la suite gratuita de editores de Google Docs basada en la web", - "tools.klavis.servers.google-docs.readme": "Integra con Google Docs para crear, editar y gestionar documentos. Redacta contenido, da formato al texto, colabora en tiempo real y accede a tus documentos mediante conversación natural.", - "tools.klavis.servers.google-drive.description": "Google Drive es un servicio de almacenamiento en la nube", - "tools.klavis.servers.google-drive.readme": "Conéctate con Google Drive para acceder, organizar y gestionar tus archivos. Busca documentos, sube archivos, comparte contenido y navega por tu almacenamiento en la nube con ayuda de IA.", - "tools.klavis.servers.google-sheets.description": "Google Sheets es una aplicación de hojas de cálculo basada en la web que permite a los usuarios crear, editar y colaborar en línea", - "tools.klavis.servers.google-sheets.readme": "Conéctate con Google Sheets para leer, escribir y analizar datos en hojas de cálculo. Realiza cálculos, genera informes, crea gráficos y gestiona datos tabulares colaborativamente con asistencia de IA.", - "tools.klavis.servers.hubspot.description": "HubSpot es un desarrollador y proveedor de software para marketing de atracción, ventas y servicio al cliente", - "tools.klavis.servers.hubspot.readme": "Integra con HubSpot para gestionar contactos, oportunidades y campañas de marketing. Accede a datos de CRM, sigue embudos de ventas, automatiza flujos de trabajo y optimiza tus operaciones comerciales y de marketing.", - "tools.klavis.servers.jira.description": "Jira es una herramienta de gestión de proyectos y seguimiento de incidencias desarrollada por Atlassian", - "tools.klavis.servers.jira.readme": "Integra con Jira para gestionar incidencias, seguir el progreso y organizar sprints. Crea tickets, actualiza estados, consulta datos de proyectos y optimiza tu flujo de trabajo de desarrollo mediante conversación natural.", - "tools.klavis.servers.notion.description": "Notion es una aplicación colaborativa de productividad y toma de notas", - "tools.klavis.servers.notion.readme": "Conéctate con Notion para acceder y gestionar tu espacio de trabajo. Crea páginas, busca contenido, actualiza bases de datos y organiza tu base de conocimiento mediante conversación natural con tu asistente de IA.", - "tools.klavis.servers.onedrive.description": "OneDrive es un servicio de alojamiento y sincronización de archivos operado por Microsoft", - "tools.klavis.servers.onedrive.readme": "Conéctate con OneDrive para acceder y gestionar tus archivos en la nube de Microsoft. Sube, descarga, comparte archivos, organiza carpetas y colabora en documentos con ayuda de IA.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail es una suite basada en la web que incluye correo, contactos, tareas y calendario de Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Integra con Outlook Mail para leer, enviar y gestionar tus correos electrónicos de Microsoft. Busca mensajes, redacta correos, gestiona carpetas y organiza tu bandeja de entrada mediante conversación natural.", - "tools.klavis.servers.salesforce.description": "Salesforce es la plataforma de gestión de relaciones con clientes (CRM) líder en el mundo que ayuda a las empresas a conectar con clientes, socios y prospectos", - "tools.klavis.servers.salesforce.readme": "Conéctate con Salesforce para gestionar relaciones con clientes y datos de ventas. Consulta registros, actualiza oportunidades, sigue clientes potenciales y automatiza tus flujos de trabajo de CRM mediante comandos en lenguaje natural.", - "tools.klavis.servers.slack.description": "Slack es una aplicación de mensajería para empresas que conecta a las personas con la información que necesitan", - "tools.klavis.servers.slack.readme": "Integra con Slack para enviar mensajes, buscar conversaciones y gestionar canales. Conéctate con tu equipo, automatiza flujos de comunicación y accede a información del espacio de trabajo mediante lenguaje natural.", - "tools.klavis.servers.supabase.description": "Servidor MCP oficial de Supabase", - "tools.klavis.servers.supabase.readme": "Integra con Supabase para gestionar tu base de datos y servicios backend. Consulta datos, gestiona autenticación, administra almacenamiento e interactúa con el backend de tu aplicación mediante conversación natural.", - "tools.klavis.servers.whatsapp.description": "Integración con la API de WhatsApp Business que permite enviar mensajes de texto, medios y gestionar conversaciones con clientes. Ideal para soporte al cliente, campañas de marketing y flujos de mensajería automatizados a través de la plataforma oficial de WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Integra con WhatsApp Business para enviar mensajes, gestionar conversaciones y conectar con tus clientes. Automatiza flujos de mensajería y gestiona comunicaciones mediante IA conversacional.", - "tools.klavis.servers.youtube.description": "YouTube es una plataforma para compartir videos donde los usuarios pueden subir, compartir y descubrir contenido. Accede a información de videos, transcripciones y metadatos de forma programática.", - "tools.klavis.servers.youtube.readme": "Conéctate con YouTube para buscar vídeos, acceder a transcripciones y obtener información de vídeos. Analiza contenido, extrae metadatos y descubre vídeos mediante conversación natural.", - "tools.klavis.servers.zendesk.description": "Zendesk es una empresa de software de atención al cliente", - "tools.klavis.servers.zendesk.readme": "Integra con Zendesk para gestionar tickets de soporte e interacciones con clientes. Crea, actualiza y sigue solicitudes de soporte, accede a datos de clientes y optimiza tus operaciones de atención al cliente.", - "tools.klavis.tools": "herramientas", - "tools.klavis.verifyAuth": "He completado la autenticación", + "tools.composio.addServer": "Agregar Servidor", + "tools.composio.authCompleted": "Autenticación Completada", + "tools.composio.authFailed": "Autenticación Fallida", + "tools.composio.authRequired": "Autenticación Requerida", + "tools.composio.connect": "Conectar", + "tools.composio.connected": "Conectado", + "tools.composio.disconnect": "Desconectar", + "tools.composio.disconnected": "Desconectado", + "tools.composio.error": "Error", + "tools.composio.groupName": "Herramientas Composio", + "tools.composio.manage": "Gestionar Composio", + "tools.composio.manageTitle": "Gestionar Integración de Composio", + "tools.composio.noServers": "No hay servidores conectados", + "tools.composio.notEnabled": "Servicio Composio no habilitado", + "tools.composio.oauthRequired": "Por favor, completa la autenticación OAuth en la nueva ventana", + "tools.composio.pendingAuth": "Autenticación Pendiente", + "tools.composio.serverCreated": "Servidor creado con éxito", + "tools.composio.serverCreatedFailed": "Error al crear el servidor", + "tools.composio.serverRemoved": "Servidor eliminado", + "tools.composio.servers": "servidores", + "tools.composio.servers.airtable.description": "Airtable es una plataforma en la nube que combina la flexibilidad de una hoja de cálculo con el poder de una base de datos, permitiendo a los equipos organizar, seguir y colaborar en proyectos con vistas personalizables y potentes funciones de automatización.", + "tools.composio.servers.airtable.readme": "Integra con Airtable para gestionar tus bases de datos y flujos de trabajo. Consulta registros, crea entradas, actualiza datos y automatiza operaciones con vistas personalizables y potentes funciones de seguimiento.", + "tools.composio.servers.cal-com.description": "Cal.com es una plataforma de programación de código abierto que te ayuda a agendar reuniones sin correos electrónicos innecesarios. Administra tipos de eventos, reservas, disponibilidad e intégralo con calendarios para una programación fluida.", + "tools.composio.servers.cal-com.readme": "Conéctate con Cal.com para gestionar tu agenda y citas. Consulta disponibilidad, programa reuniones, gestiona tipos de eventos y automatiza tu calendario mediante conversación natural.", + "tools.composio.servers.clickup.description": "ClickUp es una plataforma integral de gestión de proyectos y productividad que ayuda a los equipos a organizar tareas, gestionar proyectos y colaborar eficazmente con flujos de trabajo personalizables y potentes funciones de seguimiento.", + "tools.composio.servers.clickup.readme": "Conéctate con ClickUp para gestionar tareas, seguir proyectos y organizar tu trabajo. Crea tareas, actualiza estados, gestiona flujos de trabajo personalizados y colabora con tu equipo mediante comandos en lenguaje natural.", + "tools.composio.servers.confluence.description": "Confluence es un espacio de trabajo en equipo donde se combinan el conocimiento y la colaboración.", + "tools.composio.servers.confluence.readme": "Conéctate con Confluence para acceder y gestionar la documentación del equipo. Busca páginas, crea contenido, organiza espacios y construye tu base de conocimiento con ayuda de IA conversacional.", + "tools.composio.servers.dropbox.description": "Solución completa de gestión de archivos para el almacenamiento en la nube de Dropbox. Sube, descarga, organiza archivos y carpetas, gestiona el uso compartido y la colaboración, maneja versiones de archivos, crea solicitudes de archivos y realiza operaciones por lotes en tus archivos y carpetas de Dropbox.", + "tools.composio.servers.dropbox.readme": "Integra con Dropbox para acceder y gestionar tus archivos. Sube, descarga, comparte archivos, organiza carpetas, gestiona versiones y administra tu almacenamiento en la nube mediante IA conversacional.", + "tools.composio.servers.figma.description": "Figma es una herramienta colaborativa de diseño de interfaces para aplicaciones web y móviles.", + "tools.composio.servers.figma.readme": "Conéctate con Figma para acceder a archivos de diseño y colaborar en proyectos. Visualiza diseños, exporta recursos, explora componentes y gestiona tu flujo de trabajo de diseño mediante conversación natural.", + "tools.composio.servers.github.description": "Servidor MCP de GitHub mejorado", + "tools.composio.servers.github.readme": "Conéctate con GitHub para gestionar repositorios, incidencias, pull requests y código. Busca código, revisa cambios, crea ramas y colabora en proyectos de desarrollo de software mediante IA conversacional.", + "tools.composio.servers.gmail.description": "Gmail es un servicio de correo electrónico gratuito proporcionado por Google", + "tools.composio.servers.gmail.readme": "Lleva el poder de Gmail directamente a tu asistente de IA. Lee, redacta y envía correos, busca en tu bandeja de entrada, gestiona etiquetas y organiza tus comunicaciones, todo mediante conversación natural.", + "tools.composio.servers.google-calendar.description": "Google Calendar es un servicio de calendario para la gestión del tiempo y programación de eventos", + "tools.composio.servers.google-calendar.readme": "Integra Google Calendar para ver, crear y gestionar tus eventos sin complicaciones. Programa reuniones, establece recordatorios, consulta disponibilidad y organiza tu tiempo mediante comandos en lenguaje natural.", + "tools.composio.servers.google-docs.description": "Google Docs es un procesador de texto incluido en la suite gratuita de editores de Google Docs basada en la web", + "tools.composio.servers.google-docs.readme": "Integra con Google Docs para crear, editar y gestionar documentos. Redacta contenido, da formato al texto, colabora en tiempo real y accede a tus documentos mediante conversación natural.", + "tools.composio.servers.google-drive.description": "Google Drive es un servicio de almacenamiento en la nube", + "tools.composio.servers.google-drive.readme": "Conéctate con Google Drive para acceder, organizar y gestionar tus archivos. Busca documentos, sube archivos, comparte contenido y navega por tu almacenamiento en la nube con ayuda de IA.", + "tools.composio.servers.google-sheets.description": "Google Sheets es una aplicación de hojas de cálculo basada en la web que permite a los usuarios crear, editar y colaborar en línea", + "tools.composio.servers.google-sheets.readme": "Conéctate con Google Sheets para leer, escribir y analizar datos en hojas de cálculo. Realiza cálculos, genera informes, crea gráficos y gestiona datos tabulares colaborativamente con asistencia de IA.", + "tools.composio.servers.hubspot.description": "HubSpot es un desarrollador y proveedor de software para marketing de atracción, ventas y servicio al cliente", + "tools.composio.servers.hubspot.readme": "Integra con HubSpot para gestionar contactos, oportunidades y campañas de marketing. Accede a datos de CRM, sigue embudos de ventas, automatiza flujos de trabajo y optimiza tus operaciones comerciales y de marketing.", + "tools.composio.servers.jira.description": "Jira es una herramienta de gestión de proyectos y seguimiento de incidencias desarrollada por Atlassian", + "tools.composio.servers.jira.readme": "Integra con Jira para gestionar incidencias, seguir el progreso y organizar sprints. Crea tickets, actualiza estados, consulta datos de proyectos y optimiza tu flujo de trabajo de desarrollo mediante conversación natural.", + "tools.composio.servers.notion.description": "Notion es una aplicación colaborativa de productividad y toma de notas", + "tools.composio.servers.notion.readme": "Conéctate con Notion para acceder y gestionar tu espacio de trabajo. Crea páginas, busca contenido, actualiza bases de datos y organiza tu base de conocimiento mediante conversación natural con tu asistente de IA.", + "tools.composio.servers.onedrive.description": "OneDrive es un servicio de alojamiento y sincronización de archivos operado por Microsoft", + "tools.composio.servers.onedrive.readme": "Conéctate con OneDrive para acceder y gestionar tus archivos en la nube de Microsoft. Sube, descarga, comparte archivos, organiza carpetas y colabora en documentos con ayuda de IA.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail es una suite basada en la web que incluye correo, contactos, tareas y calendario de Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Integra con Outlook Mail para leer, enviar y gestionar tus correos electrónicos de Microsoft. Busca mensajes, redacta correos, gestiona carpetas y organiza tu bandeja de entrada mediante conversación natural.", + "tools.composio.servers.salesforce.description": "Salesforce es la plataforma de gestión de relaciones con clientes (CRM) líder en el mundo que ayuda a las empresas a conectar con clientes, socios y prospectos", + "tools.composio.servers.salesforce.readme": "Conéctate con Salesforce para gestionar relaciones con clientes y datos de ventas. Consulta registros, actualiza oportunidades, sigue clientes potenciales y automatiza tus flujos de trabajo de CRM mediante comandos en lenguaje natural.", + "tools.composio.servers.slack.description": "Slack es una aplicación de mensajería para empresas que conecta a las personas con la información que necesitan", + "tools.composio.servers.slack.readme": "Integra con Slack para enviar mensajes, buscar conversaciones y gestionar canales. Conéctate con tu equipo, automatiza flujos de comunicación y accede a información del espacio de trabajo mediante lenguaje natural.", + "tools.composio.servers.supabase.description": "Servidor MCP oficial de Supabase", + "tools.composio.servers.supabase.readme": "Integra con Supabase para gestionar tu base de datos y servicios backend. Consulta datos, gestiona autenticación, administra almacenamiento e interactúa con el backend de tu aplicación mediante conversación natural.", + "tools.composio.servers.whatsapp.description": "Integración con la API de WhatsApp Business que permite enviar mensajes de texto, medios y gestionar conversaciones con clientes. Ideal para soporte al cliente, campañas de marketing y flujos de mensajería automatizados a través de la plataforma oficial de WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Integra con WhatsApp Business para enviar mensajes, gestionar conversaciones y conectar con tus clientes. Automatiza flujos de mensajería y gestiona comunicaciones mediante IA conversacional.", + "tools.composio.servers.youtube.description": "YouTube es una plataforma para compartir videos donde los usuarios pueden subir, compartir y descubrir contenido. Accede a información de videos, transcripciones y metadatos de forma programática.", + "tools.composio.servers.youtube.readme": "Conéctate con YouTube para buscar vídeos, acceder a transcripciones y obtener información de vídeos. Analiza contenido, extrae metadatos y descubre vídeos mediante conversación natural.", + "tools.composio.servers.zendesk.description": "Zendesk es una empresa de software de atención al cliente", + "tools.composio.servers.zendesk.readme": "Integra con Zendesk para gestionar tickets de soporte e interacciones con clientes. Crea, actualiza y sigue solicitudes de soporte, accede a datos de clientes y optimiza tus operaciones de atención al cliente.", + "tools.composio.tools": "herramientas", + "tools.composio.verifyAuth": "He completado la autenticación", "tools.lobehubSkill.authorize": "Autorizar", "tools.lobehubSkill.connect": "Conectar", "tools.lobehubSkill.connected": "Conectado", diff --git a/locales/fa-IR/setting.json b/locales/fa-IR/setting.json index 09ade4cac32..852ecf8394f 100644 --- a/locales/fa-IR/setting.json +++ b/locales/fa-IR/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "حذف نصب {{name}}", "tools.builtins.uninstalled": "حذف نصب شد", "tools.disabled": "مدل فعلی از فراخوانی توابع پشتیبانی نمی‌کند و نمی‌تواند از این مهارت استفاده کند", - "tools.klavis.addServer": "افزودن سرور", - "tools.klavis.authCompleted": "احراز هویت کامل شد", - "tools.klavis.authFailed": "احراز هویت ناموفق بود", - "tools.klavis.authRequired": "احراز هویت لازم است", - "tools.klavis.connect": "اتصال", - "tools.klavis.connected": "متصل شد", - "tools.klavis.disconnect": "قطع اتصال", - "tools.klavis.disconnected": "قطع اتصال", - "tools.klavis.error": "خطا", - "tools.klavis.groupName": "ابزارهای Klavis", - "tools.klavis.manage": "مدیریت Klavis", - "tools.klavis.manageTitle": "مدیریت یکپارچه‌سازی Klavis", - "tools.klavis.noServers": "هیچ سرور متصلی وجود ندارد", - "tools.klavis.notEnabled": "سرویس Klavis فعال نیست", - "tools.klavis.oauthRequired": "لطفاً احراز هویت OAuth را در پنجره جدید کامل کنید", - "tools.klavis.pendingAuth": "در انتظار احراز هویت", - "tools.klavis.remove": "حذف", - "tools.klavis.removeConfirm.desc": "{{name}} به طور دائمی از خدمات متصل شما حذف خواهد شد. این اقدام قابل بازگشت نیست.", - "tools.klavis.removeConfirm.title": "حذف {{name}}؟", - "tools.klavis.serverCreated": "سرور با موفقیت ایجاد شد", - "tools.klavis.serverCreatedFailed": "ایجاد سرور ناموفق بود", - "tools.klavis.serverRemoved": "سرور حذف شد", - "tools.klavis.servers": "سرورها", - "tools.klavis.servers.airtable.description": "Airtable یک پلتفرم پایگاه داده و صفحه‌گسترده مبتنی بر ابر است که انعطاف‌پذیری صفحه‌گسترده را با قدرت پایگاه داده ترکیب می‌کند و به تیم‌ها امکان می‌دهد پروژه‌ها را با نماهای قابل تنظیم و ویژگی‌های قدرتمند خودکارسازی سازمان‌دهی، پیگیری و مدیریت کنند.", - "tools.klavis.servers.airtable.readme": "با Airtable یکپارچه شوید تا پایگاه‌های داده و جریان‌های کاری خود را مدیریت کنید. رکوردها را جستجو کرده، ورودی ایجاد کنید، داده‌ها را به‌روزرسانی کرده و عملیات را با نماهای قابل تنظیم و قابلیت‌های پیگیری قدرتمند خودکارسازی نمایید.", - "tools.klavis.servers.cal-com.description": "Cal.com یک پلتفرم زمان‌بندی متن‌باز است که به شما کمک می‌کند بدون ایمیل‌های رفت‌وبرگشتی جلسات را برنامه‌ریزی کنید. انواع رویداد، رزروها، در دسترس بودن را مدیریت کرده و با تقویم‌ها برای زمان‌بندی یکپارچه قرار ملاقات‌ها یکپارچه شوید.", - "tools.klavis.servers.cal-com.readme": "به Cal.com متصل شوید تا برنامه‌ریزی و قرارهای خود را مدیریت کنید. در دسترس بودن را مشاهده کرده، جلسات را رزرو کنید، انواع رویدادها را مدیریت کرده و تقویم خود را از طریق مکالمه طبیعی خودکارسازی نمایید.", - "tools.klavis.servers.clickup.description": "ClickUp یک پلتفرم جامع مدیریت پروژه و بهره‌وری است که به تیم‌ها کمک می‌کند وظایف را سازمان‌دهی کرده، پروژه‌ها را مدیریت کرده و با جریان‌های کاری قابل تنظیم و ویژگی‌های پیگیری قدرتمند به‌طور مؤثر همکاری کنند.", - "tools.klavis.servers.clickup.readme": "به ClickUp متصل شوید تا وظایف را مدیریت کرده، پروژه‌ها را پیگیری کرده و کار خود را سازماندهی کنید. وظایف ایجاد کرده، وضعیت‌ها را به‌روزرسانی کنید، جریان‌های کاری سفارشی را مدیریت کرده و با تیم خود از طریق دستورات زبان طبیعی همکاری نمایید.", - "tools.klavis.servers.confluence.description": "Confluence یک فضای کاری تیمی است که دانش و همکاری را به هم پیوند می‌دهد.", - "tools.klavis.servers.confluence.readme": "به Confluence متصل شوید تا به مستندات تیمی دسترسی داشته و آن را مدیریت کنید. صفحات را جستجو کرده، محتوا ایجاد کنید، فضاها را سازماندهی کرده و پایگاه دانشی خود را با کمک هوش مصنوعی مکالمه‌ای بسازید.", - "tools.klavis.servers.dropbox.description": "راهکار کامل مدیریت فایل برای فضای ابری Dropbox. بارگذاری، دانلود، سازمان‌دهی فایل‌ها و پوشه‌ها، مدیریت اشتراک‌گذاری و همکاری، مدیریت نسخه‌های فایل، ایجاد درخواست فایل و انجام عملیات دسته‌ای روی فایل‌ها و پوشه‌های Dropbox.", - "tools.klavis.servers.dropbox.readme": "با Dropbox یکپارچه شوید تا به فایل‌های خود دسترسی داشته و آن‌ها را مدیریت کنید. فایل‌ها را بارگذاری، دانلود و به اشتراک بگذارید، پوشه‌ها را مدیریت کرده، نسخه‌های فایل را کنترل کرده و فضای ابری خود را از طریق هوش مصنوعی سازماندهی نمایید.", - "tools.klavis.servers.figma.description": "Figma یک ابزار طراحی رابط کاربری مشارکتی برای برنامه‌های وب و موبایل است.", - "tools.klavis.servers.figma.readme": "به Figma متصل شوید تا به فایل‌های طراحی دسترسی داشته و در پروژه‌ها همکاری کنید. طراحی‌ها را مشاهده کرده، منابع را صادر کنید، اجزا را مرور کرده و جریان کاری طراحی خود را از طریق مکالمه طبیعی مدیریت نمایید.", - "tools.klavis.servers.github.description": "سرور MCP پیشرفته GitHub", - "tools.klavis.servers.github.readme": "به GitHub متصل شوید تا مخازن، مسائل، درخواست‌های pull و کد را مدیریت کنید. کد را جستجو کرده، تغییرات را بازبینی کنید، شاخه ایجاد کرده و در پروژه‌های توسعه نرم‌افزار از طریق هوش مصنوعی مکالمه‌ای همکاری نمایید.", - "tools.klavis.servers.gmail.description": "Gmail یک سرویس ایمیل رایگان ارائه‌شده توسط گوگل است.", - "tools.klavis.servers.gmail.readme": "قدرت Gmail را مستقیماً به دستیار هوش مصنوعی خود بیاورید. ایمیل‌ها را بخوانید، بنویسید و ارسال کنید، در صندوق ورودی جستجو کرده، برچسب‌ها را مدیریت کرده و ارتباطات خود را از طریق مکالمه طبیعی سازماندهی نمایید.", - "tools.klavis.servers.google-calendar.description": "Google Calendar یک سرویس تقویم برای مدیریت زمان و برنامه‌ریزی است.", - "tools.klavis.servers.google-calendar.readme": "Google Calendar را یکپارچه کنید تا رویدادهای خود را مشاهده، ایجاد و مدیریت نمایید. جلسات را برنامه‌ریزی کرده، یادآورها را تنظیم کنید، در دسترس بودن را بررسی کرده و زمان خود را از طریق دستورات زبان طبیعی هماهنگ نمایید.", - "tools.klavis.servers.google-docs.description": "Google Docs یک پردازشگر متن است که بخشی از مجموعه ویرایشگرهای آنلاین رایگان گوگل می‌باشد.", - "tools.klavis.servers.google-docs.readme": "با Google Docs یکپارچه شوید تا اسناد را ایجاد، ویرایش و مدیریت کنید. محتوا بنویسید، متن را قالب‌بندی کرده، به‌صورت هم‌زمان همکاری کنید و از طریق مکالمه طبیعی به اسناد خود دسترسی داشته باشید.", - "tools.klavis.servers.google-drive.description": "Google Drive یک سرویس ذخیره‌سازی ابری است.", - "tools.klavis.servers.google-drive.readme": "به Google Drive متصل شوید تا به فایل‌های خود دسترسی داشته، آن‌ها را سازماندهی و مدیریت کنید. اسناد را جستجو کرده، فایل‌ها را بارگذاری کنید، محتوا را به اشتراک بگذارید و فضای ابری خود را به‌صورت مؤثر با کمک هوش مصنوعی مرور نمایید.", - "tools.klavis.servers.google-sheets.description": "Google Sheets یک برنامه صفحه‌گسترده مبتنی بر وب است که به کاربران امکان می‌دهد به‌صورت آنلاین صفحه‌گسترده ایجاد، ویرایش و به‌صورت مشترک کار کنند.", - "tools.klavis.servers.google-sheets.readme": "به Google Sheets متصل شوید تا داده‌های صفحه‌گسترده را بخوانید، بنویسید و تحلیل کنید. محاسبات انجام دهید، گزارش تولید کنید، نمودار بسازید و داده‌های جدولی را به‌صورت مشارکتی با کمک هوش مصنوعی مدیریت نمایید.", - "tools.klavis.servers.hubspot.description": "HubSpot توسعه‌دهنده نرم‌افزارهای بازاریابی درون‌گرا، فروش و خدمات مشتری است.", - "tools.klavis.servers.hubspot.readme": "با HubSpot یکپارچه شوید تا مخاطبین، معاملات و کمپین‌های بازاریابی را مدیریت کنید. به داده‌های CRM دسترسی داشته، جریان فروش را پیگیری کرده، جریان‌های کاری را خودکارسازی کرده و عملیات فروش و بازاریابی خود را بهینه نمایید.", - "tools.klavis.servers.jira.description": "Jira یک ابزار مدیریت پروژه و پیگیری مسائل است که توسط Atlassian توسعه یافته است.", - "tools.klavis.servers.jira.readme": "با Jira یکپارچه شوید تا مسائل را مدیریت کرده، پیشرفت را پیگیری کرده و اسپرینت‌ها را سازماندهی کنید. تیکت ایجاد کرده، وضعیت‌ها را به‌روزرسانی کنید، داده‌های پروژه را جستجو کرده و جریان کاری توسعه خود را از طریق مکالمه طبیعی بهینه نمایید.", - "tools.klavis.servers.notion.description": "Notion یک برنامه بهره‌وری مشارکتی و یادداشت‌برداری است.", - "tools.klavis.servers.notion.readme": "به Notion متصل شوید تا به فضای کاری خود دسترسی داشته و آن را مدیریت کنید. صفحات ایجاد کرده، محتوا را جستجو کنید، پایگاه‌های داده را به‌روزرسانی کرده و پایگاه دانشی خود را از طریق مکالمه طبیعی با دستیار هوش مصنوعی سازماندهی نمایید.", - "tools.klavis.servers.onedrive.description": "OneDrive یک سرویس میزبانی و همگام‌سازی فایل است که توسط مایکروسافت ارائه می‌شود.", - "tools.klavis.servers.onedrive.readme": "به OneDrive متصل شوید تا به فایل‌های ابری مایکروسافت خود دسترسی داشته و آن‌ها را مدیریت کنید. فایل‌ها را بارگذاری، دانلود و به اشتراک بگذارید، پوشه‌ها را سازماندهی کرده و در اسناد با کمک هوش مصنوعی همکاری نمایید.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail یک مجموعه مبتنی بر وب از خدمات ایمیل، مخاطبین، وظایف و تقویم از مایکروسافت است.", - "tools.klavis.servers.outlook-mail.readme": "با Outlook Mail یکپارچه شوید تا ایمیل‌های مایکروسافت خود را بخوانید، ارسال کرده و مدیریت کنید. پیام‌ها را جستجو کرده، ایمیل بنویسید، پوشه‌ها را مدیریت کرده و صندوق ورودی خود را از طریق مکالمه طبیعی سازماندهی نمایید.", - "tools.klavis.servers.salesforce.description": "Salesforce پیشروترین پلتفرم مدیریت ارتباط با مشتری (CRM) در جهان است که به کسب‌وکارها کمک می‌کند با مشتریان، شرکا و مشتریان بالقوه ارتباط برقرار کنند.", - "tools.klavis.servers.salesforce.readme": "به Salesforce متصل شوید تا روابط مشتری و داده‌های فروش را مدیریت کنید. رکوردها را جستجو کرده، فرصت‌ها را به‌روزرسانی کنید، سرنخ‌ها را پیگیری کرده و جریان‌های کاری CRM خود را از طریق دستورات زبان طبیعی خودکارسازی نمایید.", - "tools.klavis.servers.slack.description": "Slack یک برنامه پیام‌رسانی برای کسب‌وکار است که افراد را به اطلاعات مورد نیازشان متصل می‌کند.", - "tools.klavis.servers.slack.readme": "با Slack یکپارچه شوید تا پیام ارسال کرده، گفتگوها را جستجو کرده و کانال‌ها را مدیریت کنید. با تیم خود ارتباط برقرار کرده، جریان‌های کاری ارتباطی را خودکارسازی کرده و به اطلاعات فضای کاری از طریق زبان طبیعی دسترسی داشته باشید.", - "tools.klavis.servers.supabase.description": "سرور رسمی MCP برای Supabase", - "tools.klavis.servers.supabase.readme": "با Supabase یکپارچه شوید تا پایگاه داده و خدمات بک‌اند خود را مدیریت کنید. داده‌ها را جستجو کرده، احراز هویت را مدیریت کنید، فضای ذخیره‌سازی را کنترل کرده و با بک‌اند برنامه خود از طریق مکالمه طبیعی تعامل داشته باشید.", - "tools.klavis.servers.whatsapp.description": "یکپارچه‌سازی با API کسب‌وکار WhatsApp که امکان ارسال پیام متنی، رسانه‌ای و مدیریت مکالمات با مشتریان را فراهم می‌کند. مناسب برای پشتیبانی مشتری، کمپین‌های بازاریابی و جریان‌های کاری پیام‌رسانی خودکار از طریق پلتفرم رسمی WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "با WhatsApp Business یکپارچه شوید تا پیام ارسال کرده، گفتگوها را مدیریت کرده و با مشتریان تعامل داشته باشید. جریان‌های کاری پیام‌رسانی را خودکارسازی کرده و ارتباطات را از طریق هوش مصنوعی مکالمه‌ای مدیریت نمایید.", - "tools.klavis.servers.youtube.description": "YouTube یک پلتفرم اشتراک‌گذاری ویدیو است که کاربران می‌توانند در آن ویدیو بارگذاری، به اشتراک‌گذاری و کشف کنند. به اطلاعات ویدیو، رونوشت‌ها و فراداده‌ها به‌صورت برنامه‌نویسی دسترسی پیدا کنید.", - "tools.klavis.servers.youtube.readme": "به YouTube متصل شوید تا ویدیوها را جستجو کرده، به رونوشت‌ها دسترسی داشته و اطلاعات ویدیو را بازیابی کنید. محتوا را تحلیل کرده، فراداده استخراج کرده و ویدیوها را از طریق مکالمه طبیعی کشف نمایید.", - "tools.klavis.servers.zendesk.description": "Zendesk یک شرکت نرم‌افزاری خدمات مشتری است.", - "tools.klavis.servers.zendesk.readme": "با Zendesk یکپارچه شوید تا تیکت‌های پشتیبانی و تعاملات مشتری را مدیریت کنید. درخواست‌های پشتیبانی را ایجاد، به‌روزرسانی و پیگیری کرده، به داده‌های مشتری دسترسی داشته و عملیات پشتیبانی خود را بهینه نمایید.", - "tools.klavis.tools": "ابزارها", - "tools.klavis.verifyAuth": "احراز هویت را کامل کرده‌ام", + "tools.composio.addServer": "افزودن سرور", + "tools.composio.authCompleted": "احراز هویت کامل شد", + "tools.composio.authFailed": "احراز هویت ناموفق بود", + "tools.composio.authRequired": "احراز هویت لازم است", + "tools.composio.connect": "اتصال", + "tools.composio.connected": "متصل شد", + "tools.composio.disconnect": "قطع اتصال", + "tools.composio.disconnected": "قطع اتصال", + "tools.composio.error": "خطا", + "tools.composio.groupName": "ابزارهای Composio", + "tools.composio.manage": "مدیریت Composio", + "tools.composio.manageTitle": "مدیریت یکپارچه‌سازی Composio", + "tools.composio.noServers": "هیچ سرور متصلی وجود ندارد", + "tools.composio.notEnabled": "سرویس Composio فعال نیست", + "tools.composio.oauthRequired": "لطفاً احراز هویت OAuth را در پنجره جدید کامل کنید", + "tools.composio.pendingAuth": "در انتظار احراز هویت", + "tools.composio.serverCreated": "سرور با موفقیت ایجاد شد", + "tools.composio.serverCreatedFailed": "ایجاد سرور ناموفق بود", + "tools.composio.serverRemoved": "سرور حذف شد", + "tools.composio.servers": "سرورها", + "tools.composio.servers.airtable.description": "Airtable یک پلتفرم پایگاه داده و صفحه‌گسترده مبتنی بر ابر است که انعطاف‌پذیری صفحه‌گسترده را با قدرت پایگاه داده ترکیب می‌کند و به تیم‌ها امکان می‌دهد پروژه‌ها را با نماهای قابل تنظیم و ویژگی‌های قدرتمند خودکارسازی سازمان‌دهی، پیگیری و مدیریت کنند.", + "tools.composio.servers.airtable.readme": "با Airtable یکپارچه شوید تا پایگاه‌های داده و جریان‌های کاری خود را مدیریت کنید. رکوردها را جستجو کرده، ورودی ایجاد کنید، داده‌ها را به‌روزرسانی کرده و عملیات را با نماهای قابل تنظیم و قابلیت‌های پیگیری قدرتمند خودکارسازی نمایید.", + "tools.composio.servers.cal-com.description": "Cal.com یک پلتفرم زمان‌بندی متن‌باز است که به شما کمک می‌کند بدون ایمیل‌های رفت‌وبرگشتی جلسات را برنامه‌ریزی کنید. انواع رویداد، رزروها، در دسترس بودن را مدیریت کرده و با تقویم‌ها برای زمان‌بندی یکپارچه قرار ملاقات‌ها یکپارچه شوید.", + "tools.composio.servers.cal-com.readme": "به Cal.com متصل شوید تا برنامه‌ریزی و قرارهای خود را مدیریت کنید. در دسترس بودن را مشاهده کرده، جلسات را رزرو کنید، انواع رویدادها را مدیریت کرده و تقویم خود را از طریق مکالمه طبیعی خودکارسازی نمایید.", + "tools.composio.servers.clickup.description": "ClickUp یک پلتفرم جامع مدیریت پروژه و بهره‌وری است که به تیم‌ها کمک می‌کند وظایف را سازمان‌دهی کرده، پروژه‌ها را مدیریت کرده و با جریان‌های کاری قابل تنظیم و ویژگی‌های پیگیری قدرتمند به‌طور مؤثر همکاری کنند.", + "tools.composio.servers.clickup.readme": "به ClickUp متصل شوید تا وظایف را مدیریت کرده، پروژه‌ها را پیگیری کرده و کار خود را سازماندهی کنید. وظایف ایجاد کرده، وضعیت‌ها را به‌روزرسانی کنید، جریان‌های کاری سفارشی را مدیریت کرده و با تیم خود از طریق دستورات زبان طبیعی همکاری نمایید.", + "tools.composio.servers.confluence.description": "Confluence یک فضای کاری تیمی است که دانش و همکاری را به هم پیوند می‌دهد.", + "tools.composio.servers.confluence.readme": "به Confluence متصل شوید تا به مستندات تیمی دسترسی داشته و آن را مدیریت کنید. صفحات را جستجو کرده، محتوا ایجاد کنید، فضاها را سازماندهی کرده و پایگاه دانشی خود را با کمک هوش مصنوعی مکالمه‌ای بسازید.", + "tools.composio.servers.dropbox.description": "راهکار کامل مدیریت فایل برای فضای ابری Dropbox. بارگذاری، دانلود، سازمان‌دهی فایل‌ها و پوشه‌ها، مدیریت اشتراک‌گذاری و همکاری، مدیریت نسخه‌های فایل، ایجاد درخواست فایل و انجام عملیات دسته‌ای روی فایل‌ها و پوشه‌های Dropbox.", + "tools.composio.servers.dropbox.readme": "با Dropbox یکپارچه شوید تا به فایل‌های خود دسترسی داشته و آن‌ها را مدیریت کنید. فایل‌ها را بارگذاری، دانلود و به اشتراک بگذارید، پوشه‌ها را مدیریت کرده، نسخه‌های فایل را کنترل کرده و فضای ابری خود را از طریق هوش مصنوعی سازماندهی نمایید.", + "tools.composio.servers.figma.description": "Figma یک ابزار طراحی رابط کاربری مشارکتی برای برنامه‌های وب و موبایل است.", + "tools.composio.servers.figma.readme": "به Figma متصل شوید تا به فایل‌های طراحی دسترسی داشته و در پروژه‌ها همکاری کنید. طراحی‌ها را مشاهده کرده، منابع را صادر کنید، اجزا را مرور کرده و جریان کاری طراحی خود را از طریق مکالمه طبیعی مدیریت نمایید.", + "tools.composio.servers.github.description": "سرور MCP پیشرفته GitHub", + "tools.composio.servers.github.readme": "به GitHub متصل شوید تا مخازن، مسائل، درخواست‌های pull و کد را مدیریت کنید. کد را جستجو کرده، تغییرات را بازبینی کنید، شاخه ایجاد کرده و در پروژه‌های توسعه نرم‌افزار از طریق هوش مصنوعی مکالمه‌ای همکاری نمایید.", + "tools.composio.servers.gmail.description": "Gmail یک سرویس ایمیل رایگان ارائه‌شده توسط گوگل است.", + "tools.composio.servers.gmail.readme": "قدرت Gmail را مستقیماً به دستیار هوش مصنوعی خود بیاورید. ایمیل‌ها را بخوانید، بنویسید و ارسال کنید، در صندوق ورودی جستجو کرده، برچسب‌ها را مدیریت کرده و ارتباطات خود را از طریق مکالمه طبیعی سازماندهی نمایید.", + "tools.composio.servers.google-calendar.description": "Google Calendar یک سرویس تقویم برای مدیریت زمان و برنامه‌ریزی است.", + "tools.composio.servers.google-calendar.readme": "Google Calendar را یکپارچه کنید تا رویدادهای خود را مشاهده، ایجاد و مدیریت نمایید. جلسات را برنامه‌ریزی کرده، یادآورها را تنظیم کنید، در دسترس بودن را بررسی کرده و زمان خود را از طریق دستورات زبان طبیعی هماهنگ نمایید.", + "tools.composio.servers.google-docs.description": "Google Docs یک پردازشگر متن است که بخشی از مجموعه ویرایشگرهای آنلاین رایگان گوگل می‌باشد.", + "tools.composio.servers.google-docs.readme": "با Google Docs یکپارچه شوید تا اسناد را ایجاد، ویرایش و مدیریت کنید. محتوا بنویسید، متن را قالب‌بندی کرده، به‌صورت هم‌زمان همکاری کنید و از طریق مکالمه طبیعی به اسناد خود دسترسی داشته باشید.", + "tools.composio.servers.google-drive.description": "Google Drive یک سرویس ذخیره‌سازی ابری است.", + "tools.composio.servers.google-drive.readme": "به Google Drive متصل شوید تا به فایل‌های خود دسترسی داشته، آن‌ها را سازماندهی و مدیریت کنید. اسناد را جستجو کرده، فایل‌ها را بارگذاری کنید، محتوا را به اشتراک بگذارید و فضای ابری خود را به‌صورت مؤثر با کمک هوش مصنوعی مرور نمایید.", + "tools.composio.servers.google-sheets.description": "Google Sheets یک برنامه صفحه‌گسترده مبتنی بر وب است که به کاربران امکان می‌دهد به‌صورت آنلاین صفحه‌گسترده ایجاد، ویرایش و به‌صورت مشترک کار کنند.", + "tools.composio.servers.google-sheets.readme": "به Google Sheets متصل شوید تا داده‌های صفحه‌گسترده را بخوانید، بنویسید و تحلیل کنید. محاسبات انجام دهید، گزارش تولید کنید، نمودار بسازید و داده‌های جدولی را به‌صورت مشارکتی با کمک هوش مصنوعی مدیریت نمایید.", + "tools.composio.servers.hubspot.description": "HubSpot توسعه‌دهنده نرم‌افزارهای بازاریابی درون‌گرا، فروش و خدمات مشتری است.", + "tools.composio.servers.hubspot.readme": "با HubSpot یکپارچه شوید تا مخاطبین، معاملات و کمپین‌های بازاریابی را مدیریت کنید. به داده‌های CRM دسترسی داشته، جریان فروش را پیگیری کرده، جریان‌های کاری را خودکارسازی کرده و عملیات فروش و بازاریابی خود را بهینه نمایید.", + "tools.composio.servers.jira.description": "Jira یک ابزار مدیریت پروژه و پیگیری مسائل است که توسط Atlassian توسعه یافته است.", + "tools.composio.servers.jira.readme": "با Jira یکپارچه شوید تا مسائل را مدیریت کرده، پیشرفت را پیگیری کرده و اسپرینت‌ها را سازماندهی کنید. تیکت ایجاد کرده، وضعیت‌ها را به‌روزرسانی کنید، داده‌های پروژه را جستجو کرده و جریان کاری توسعه خود را از طریق مکالمه طبیعی بهینه نمایید.", + "tools.composio.servers.notion.description": "Notion یک برنامه بهره‌وری مشارکتی و یادداشت‌برداری است.", + "tools.composio.servers.notion.readme": "به Notion متصل شوید تا به فضای کاری خود دسترسی داشته و آن را مدیریت کنید. صفحات ایجاد کرده، محتوا را جستجو کنید، پایگاه‌های داده را به‌روزرسانی کرده و پایگاه دانشی خود را از طریق مکالمه طبیعی با دستیار هوش مصنوعی سازماندهی نمایید.", + "tools.composio.servers.onedrive.description": "OneDrive یک سرویس میزبانی و همگام‌سازی فایل است که توسط مایکروسافت ارائه می‌شود.", + "tools.composio.servers.onedrive.readme": "به OneDrive متصل شوید تا به فایل‌های ابری مایکروسافت خود دسترسی داشته و آن‌ها را مدیریت کنید. فایل‌ها را بارگذاری، دانلود و به اشتراک بگذارید، پوشه‌ها را سازماندهی کرده و در اسناد با کمک هوش مصنوعی همکاری نمایید.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail یک مجموعه مبتنی بر وب از خدمات ایمیل، مخاطبین، وظایف و تقویم از مایکروسافت است.", + "tools.composio.servers.outlook-mail.readme": "با Outlook Mail یکپارچه شوید تا ایمیل‌های مایکروسافت خود را بخوانید، ارسال کرده و مدیریت کنید. پیام‌ها را جستجو کرده، ایمیل بنویسید، پوشه‌ها را مدیریت کرده و صندوق ورودی خود را از طریق مکالمه طبیعی سازماندهی نمایید.", + "tools.composio.servers.salesforce.description": "Salesforce پیشروترین پلتفرم مدیریت ارتباط با مشتری (CRM) در جهان است که به کسب‌وکارها کمک می‌کند با مشتریان، شرکا و مشتریان بالقوه ارتباط برقرار کنند.", + "tools.composio.servers.salesforce.readme": "به Salesforce متصل شوید تا روابط مشتری و داده‌های فروش را مدیریت کنید. رکوردها را جستجو کرده، فرصت‌ها را به‌روزرسانی کنید، سرنخ‌ها را پیگیری کرده و جریان‌های کاری CRM خود را از طریق دستورات زبان طبیعی خودکارسازی نمایید.", + "tools.composio.servers.slack.description": "Slack یک برنامه پیام‌رسانی برای کسب‌وکار است که افراد را به اطلاعات مورد نیازشان متصل می‌کند.", + "tools.composio.servers.slack.readme": "با Slack یکپارچه شوید تا پیام ارسال کرده، گفتگوها را جستجو کرده و کانال‌ها را مدیریت کنید. با تیم خود ارتباط برقرار کرده، جریان‌های کاری ارتباطی را خودکارسازی کرده و به اطلاعات فضای کاری از طریق زبان طبیعی دسترسی داشته باشید.", + "tools.composio.servers.supabase.description": "سرور رسمی MCP برای Supabase", + "tools.composio.servers.supabase.readme": "با Supabase یکپارچه شوید تا پایگاه داده و خدمات بک‌اند خود را مدیریت کنید. داده‌ها را جستجو کرده، احراز هویت را مدیریت کنید، فضای ذخیره‌سازی را کنترل کرده و با بک‌اند برنامه خود از طریق مکالمه طبیعی تعامل داشته باشید.", + "tools.composio.servers.whatsapp.description": "یکپارچه‌سازی با API کسب‌وکار WhatsApp که امکان ارسال پیام متنی، رسانه‌ای و مدیریت مکالمات با مشتریان را فراهم می‌کند. مناسب برای پشتیبانی مشتری، کمپین‌های بازاریابی و جریان‌های کاری پیام‌رسانی خودکار از طریق پلتفرم رسمی WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "با WhatsApp Business یکپارچه شوید تا پیام ارسال کرده، گفتگوها را مدیریت کرده و با مشتریان تعامل داشته باشید. جریان‌های کاری پیام‌رسانی را خودکارسازی کرده و ارتباطات را از طریق هوش مصنوعی مکالمه‌ای مدیریت نمایید.", + "tools.composio.servers.youtube.description": "YouTube یک پلتفرم اشتراک‌گذاری ویدیو است که کاربران می‌توانند در آن ویدیو بارگذاری، به اشتراک‌گذاری و کشف کنند. به اطلاعات ویدیو، رونوشت‌ها و فراداده‌ها به‌صورت برنامه‌نویسی دسترسی پیدا کنید.", + "tools.composio.servers.youtube.readme": "به YouTube متصل شوید تا ویدیوها را جستجو کرده، به رونوشت‌ها دسترسی داشته و اطلاعات ویدیو را بازیابی کنید. محتوا را تحلیل کرده، فراداده استخراج کرده و ویدیوها را از طریق مکالمه طبیعی کشف نمایید.", + "tools.composio.servers.zendesk.description": "Zendesk یک شرکت نرم‌افزاری خدمات مشتری است.", + "tools.composio.servers.zendesk.readme": "با Zendesk یکپارچه شوید تا تیکت‌های پشتیبانی و تعاملات مشتری را مدیریت کنید. درخواست‌های پشتیبانی را ایجاد، به‌روزرسانی و پیگیری کرده، به داده‌های مشتری دسترسی داشته و عملیات پشتیبانی خود را بهینه نمایید.", + "tools.composio.tools": "ابزارها", + "tools.composio.verifyAuth": "احراز هویت را کامل کرده‌ام", "tools.lobehubSkill.authorize": "اعطا مجوز", "tools.lobehubSkill.connect": "اتصال", "tools.lobehubSkill.connected": "متصل شد", diff --git a/locales/fr-FR/setting.json b/locales/fr-FR/setting.json index 34268aefd9f..8481e6444a8 100644 --- a/locales/fr-FR/setting.json +++ b/locales/fr-FR/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Désinstaller {{name}}", "tools.builtins.uninstalled": "Désinstallé", "tools.disabled": "Le modèle actuel ne prend pas en charge les appels de fonction et ne peut pas utiliser cette compétence", - "tools.klavis.addServer": "Ajouter un serveur", - "tools.klavis.authCompleted": "Authentification terminée", - "tools.klavis.authFailed": "Échec de l’authentification", - "tools.klavis.authRequired": "Authentification requise", - "tools.klavis.connect": "Connecter", - "tools.klavis.connected": "Connecté", - "tools.klavis.disconnect": "Déconnecter", - "tools.klavis.disconnected": "Déconnecté", - "tools.klavis.error": "Erreur", - "tools.klavis.groupName": "Outils Klavis", - "tools.klavis.manage": "Gérer Klavis", - "tools.klavis.manageTitle": "Gérer l’intégration Klavis", - "tools.klavis.noServers": "Aucun serveur connecté", - "tools.klavis.notEnabled": "Service Klavis non activé", - "tools.klavis.oauthRequired": "Veuillez compléter l’authentification OAuth dans la nouvelle fenêtre", - "tools.klavis.pendingAuth": "Authentification en attente", - "tools.klavis.remove": "Supprimer", - "tools.klavis.removeConfirm.desc": "{{name}} sera définitivement supprimé de vos services connectés. Cette action est irréversible.", - "tools.klavis.removeConfirm.title": "Supprimer {{name}} ?", - "tools.klavis.serverCreated": "Serveur créé avec succès", - "tools.klavis.serverCreatedFailed": "Échec de la création du serveur", - "tools.klavis.serverRemoved": "Serveur supprimé", - "tools.klavis.servers": "serveurs", - "tools.klavis.servers.airtable.description": "Airtable est une plateforme de base de données et de tableur basée sur le cloud qui combine la flexibilité d’un tableur avec la puissance d’une base de données, permettant aux équipes d’organiser, suivre et collaborer sur des projets avec des vues personnalisables et des fonctionnalités d’automatisation puissantes.", - "tools.klavis.servers.airtable.readme": "Intégrez Airtable pour gérer vos bases de données et vos flux de travail. Interrogez des enregistrements, créez des entrées, mettez à jour des données et automatisez vos opérations avec des vues personnalisables et des fonctionnalités de suivi puissantes.", - "tools.klavis.servers.cal-com.description": "Cal.com est une plateforme de planification open source qui vous aide à organiser des réunions sans échanges d’e-mails incessants. Gérez les types d’événements, les réservations, la disponibilité et intégrez vos calendriers pour une planification fluide.", - "tools.klavis.servers.cal-com.readme": "Connectez-vous à Cal.com pour gérer vos plannings et rendez-vous. Consultez vos disponibilités, planifiez des réunions, gérez les types d'événements et automatisez votre calendrier via une conversation naturelle.", - "tools.klavis.servers.clickup.description": "ClickUp est une plateforme complète de gestion de projet et de productivité qui aide les équipes à organiser les tâches, gérer les projets et collaborer efficacement grâce à des flux de travail personnalisables et des fonctionnalités de suivi puissantes.", - "tools.klavis.servers.clickup.readme": "Connectez-vous à ClickUp pour gérer vos tâches, suivre vos projets et organiser votre travail. Créez des tâches, mettez à jour les statuts, gérez des flux de travail personnalisés et collaborez avec votre équipe via des commandes en langage naturel.", - "tools.klavis.servers.confluence.description": "Confluence est un espace de travail collaboratif où se rencontrent la connaissance et la collaboration.", - "tools.klavis.servers.confluence.readme": "Connectez-vous à Confluence pour accéder à la documentation de votre équipe et la gérer. Recherchez des pages, créez du contenu, organisez des espaces et développez votre base de connaissances avec l'aide de l'IA conversationnelle.", - "tools.klavis.servers.dropbox.description": "Solution complète de gestion de fichiers pour le stockage cloud Dropbox. Téléversez, téléchargez, organisez des fichiers et dossiers, gérez le partage et la collaboration, gérez les versions de fichiers, créez des demandes de fichiers et effectuez des opérations groupées sur vos fichiers et dossiers Dropbox.", - "tools.klavis.servers.dropbox.readme": "Intégrez Dropbox pour accéder à vos fichiers et les gérer. Téléversez, téléchargez, partagez des fichiers, gérez des dossiers, gérez les versions de fichiers et organisez votre stockage cloud via l'IA conversationnelle.", - "tools.klavis.servers.figma.description": "Figma est un outil collaboratif de conception d’interfaces pour les applications web et mobiles.", - "tools.klavis.servers.figma.readme": "Connectez-vous à Figma pour accéder à vos fichiers de design et collaborer sur vos projets. Visualisez des maquettes, exportez des ressources, explorez des composants et gérez votre flux de travail de design via une conversation naturelle.", - "tools.klavis.servers.github.description": "Serveur MCP GitHub amélioré", - "tools.klavis.servers.github.readme": "Connectez-vous à GitHub pour gérer vos dépôts, problèmes, pull requests et code. Recherchez du code, examinez des modifications, créez des branches et collaborez sur des projets de développement logiciel via l'IA conversationnelle.", - "tools.klavis.servers.gmail.description": "Gmail est un service de messagerie gratuit proposé par Google", - "tools.klavis.servers.gmail.readme": "Profitez de la puissance de Gmail directement dans votre assistant IA. Lisez, rédigez et envoyez des e-mails, recherchez dans votre boîte de réception, gérez les libellés et organisez vos communications — le tout par conversation naturelle.", - "tools.klavis.servers.google-calendar.description": "Google Agenda est un service de calendrier de gestion du temps et de planification", - "tools.klavis.servers.google-calendar.readme": "Intégrez Google Agenda pour consulter, créer et gérer vos événements en toute fluidité. Planifiez des réunions, définissez des rappels, vérifiez les disponibilités et organisez votre emploi du temps via des commandes en langage naturel.", - "tools.klavis.servers.google-docs.description": "Google Docs est un traitement de texte inclus dans la suite gratuite d’éditeurs Google Docs basée sur le web", - "tools.klavis.servers.google-docs.readme": "Intégrez Google Docs pour créer, modifier et gérer vos documents. Rédigez du contenu, mettez en forme du texte, collaborez en temps réel et accédez à vos documents via une conversation naturelle.", - "tools.klavis.servers.google-drive.description": "Google Drive est un service de stockage cloud", - "tools.klavis.servers.google-drive.readme": "Connectez-vous à Google Drive pour accéder à vos fichiers, les organiser et les gérer. Recherchez des documents, téléversez des fichiers, partagez du contenu et naviguez efficacement dans votre stockage cloud grâce à l'assistance de l'IA.", - "tools.klavis.servers.google-sheets.description": "Google Sheets est une application de tableur en ligne qui permet aux utilisateurs de créer, modifier et collaborer sur des feuilles de calcul", - "tools.klavis.servers.google-sheets.readme": "Connectez-vous à Google Sheets pour lire, écrire et analyser des données de tableur. Effectuez des calculs, générez des rapports, créez des graphiques et gérez des données tabulaires en collaboration avec l'aide de l'IA.", - "tools.klavis.servers.hubspot.description": "HubSpot est un éditeur de logiciels pour le marketing entrant, les ventes et le service client", - "tools.klavis.servers.hubspot.readme": "Intégrez HubSpot pour gérer vos contacts, opportunités et campagnes marketing. Accédez aux données CRM, suivez les pipelines, automatisez les flux de travail et optimisez vos opérations commerciales et marketing.", - "tools.klavis.servers.jira.description": "Jira est un outil de gestion de projet et de suivi des problèmes développé par Atlassian", - "tools.klavis.servers.jira.readme": "Intégrez Jira pour gérer les tickets, suivre les progrès et organiser les sprints. Créez des tickets, mettez à jour les statuts, interrogez les données de projet et optimisez votre flux de développement via une conversation naturelle.", - "tools.klavis.servers.notion.description": "Notion est une application collaborative de productivité et de prise de notes", - "tools.klavis.servers.notion.readme": "Connectez-vous à Notion pour accéder à votre espace de travail et le gérer. Créez des pages, recherchez du contenu, mettez à jour des bases de données et organisez votre base de connaissances — le tout via une conversation naturelle avec votre assistant IA.", - "tools.klavis.servers.onedrive.description": "OneDrive est un service d’hébergement et de synchronisation de fichiers opéré par Microsoft", - "tools.klavis.servers.onedrive.readme": "Connectez-vous à OneDrive pour accéder à vos fichiers cloud Microsoft et les gérer. Téléversez, téléchargez, partagez des fichiers, organisez des dossiers et collaborez sur des documents grâce à l'assistance de l'IA.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail est une suite web de messagerie, contacts, tâches et calendrier proposée par Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Intégrez Outlook Mail pour lire, envoyer et gérer vos e-mails Microsoft. Recherchez des messages, rédigez des e-mails, gérez des dossiers et organisez votre boîte de réception via une conversation naturelle.", - "tools.klavis.servers.salesforce.description": "Salesforce est la principale plateforme de gestion de la relation client (CRM) au monde, aidant les entreprises à se connecter avec leurs clients, partenaires et prospects", - "tools.klavis.servers.salesforce.readme": "Connectez-vous à Salesforce pour gérer vos relations clients et données commerciales. Interrogez des enregistrements, mettez à jour des opportunités, suivez des prospects et automatisez vos flux CRM via des commandes en langage naturel.", - "tools.klavis.servers.slack.description": "Slack est une application de messagerie professionnelle qui connecte les personnes aux informations dont elles ont besoin", - "tools.klavis.servers.slack.readme": "Intégrez Slack pour envoyer des messages, rechercher des conversations et gérer des canaux. Restez connecté avec votre équipe, automatisez les communications et accédez aux informations de votre espace de travail via le langage naturel.", - "tools.klavis.servers.supabase.description": "Serveur MCP officiel de Supabase", - "tools.klavis.servers.supabase.readme": "Intégrez Supabase pour gérer votre base de données et vos services backend. Interrogez des données, gérez l'authentification, manipulez le stockage et interagissez avec votre backend applicatif via une conversation naturelle.", - "tools.klavis.servers.whatsapp.description": "Intégration de l’API WhatsApp Business permettant l’envoi de messages texte, de médias et la gestion des conversations avec les clients. Parfait pour le support client, les campagnes marketing et les flux de messagerie automatisés via la plateforme officielle WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Intégrez WhatsApp Business pour envoyer des messages, gérer des conversations et interagir avec vos clients. Automatisez les flux de messagerie et gérez vos communications via l'IA conversationnelle.", - "tools.klavis.servers.youtube.description": "YouTube est une plateforme de partage de vidéos où les utilisateurs peuvent téléverser, partager et découvrir du contenu. Accédez aux informations, transcriptions et métadonnées des vidéos de manière programmatique.", - "tools.klavis.servers.youtube.readme": "Connectez-vous à YouTube pour rechercher des vidéos, accéder aux transcriptions et récupérer des informations. Analysez le contenu, extrayez des métadonnées et découvrez des vidéos via une conversation naturelle.", - "tools.klavis.servers.zendesk.description": "Zendesk est une entreprise de logiciels de service client", - "tools.klavis.servers.zendesk.readme": "Intégrez Zendesk pour gérer les tickets de support et les interactions clients. Créez, mettez à jour et suivez les demandes d'assistance, accédez aux données clients et optimisez vos opérations de support.", - "tools.klavis.tools": "outils", - "tools.klavis.verifyAuth": "J’ai terminé l’authentification", + "tools.composio.addServer": "Ajouter un serveur", + "tools.composio.authCompleted": "Authentification terminée", + "tools.composio.authFailed": "Échec de l’authentification", + "tools.composio.authRequired": "Authentification requise", + "tools.composio.connect": "Connecter", + "tools.composio.connected": "Connecté", + "tools.composio.disconnect": "Déconnecter", + "tools.composio.disconnected": "Déconnecté", + "tools.composio.error": "Erreur", + "tools.composio.groupName": "Outils Composio", + "tools.composio.manage": "Gérer Composio", + "tools.composio.manageTitle": "Gérer l’intégration Composio", + "tools.composio.noServers": "Aucun serveur connecté", + "tools.composio.notEnabled": "Service Composio non activé", + "tools.composio.oauthRequired": "Veuillez compléter l’authentification OAuth dans la nouvelle fenêtre", + "tools.composio.pendingAuth": "Authentification en attente", + "tools.composio.serverCreated": "Serveur créé avec succès", + "tools.composio.serverCreatedFailed": "Échec de la création du serveur", + "tools.composio.serverRemoved": "Serveur supprimé", + "tools.composio.servers": "serveurs", + "tools.composio.servers.airtable.description": "Airtable est une plateforme de base de données et de tableur basée sur le cloud qui combine la flexibilité d’un tableur avec la puissance d’une base de données, permettant aux équipes d’organiser, suivre et collaborer sur des projets avec des vues personnalisables et des fonctionnalités d’automatisation puissantes.", + "tools.composio.servers.airtable.readme": "Intégrez Airtable pour gérer vos bases de données et vos flux de travail. Interrogez des enregistrements, créez des entrées, mettez à jour des données et automatisez vos opérations avec des vues personnalisables et des fonctionnalités de suivi puissantes.", + "tools.composio.servers.cal-com.description": "Cal.com est une plateforme de planification open source qui vous aide à organiser des réunions sans échanges d’e-mails incessants. Gérez les types d’événements, les réservations, la disponibilité et intégrez vos calendriers pour une planification fluide.", + "tools.composio.servers.cal-com.readme": "Connectez-vous à Cal.com pour gérer vos plannings et rendez-vous. Consultez vos disponibilités, planifiez des réunions, gérez les types d'événements et automatisez votre calendrier via une conversation naturelle.", + "tools.composio.servers.clickup.description": "ClickUp est une plateforme complète de gestion de projet et de productivité qui aide les équipes à organiser les tâches, gérer les projets et collaborer efficacement grâce à des flux de travail personnalisables et des fonctionnalités de suivi puissantes.", + "tools.composio.servers.clickup.readme": "Connectez-vous à ClickUp pour gérer vos tâches, suivre vos projets et organiser votre travail. Créez des tâches, mettez à jour les statuts, gérez des flux de travail personnalisés et collaborez avec votre équipe via des commandes en langage naturel.", + "tools.composio.servers.confluence.description": "Confluence est un espace de travail collaboratif où se rencontrent la connaissance et la collaboration.", + "tools.composio.servers.confluence.readme": "Connectez-vous à Confluence pour accéder à la documentation de votre équipe et la gérer. Recherchez des pages, créez du contenu, organisez des espaces et développez votre base de connaissances avec l'aide de l'IA conversationnelle.", + "tools.composio.servers.dropbox.description": "Solution complète de gestion de fichiers pour le stockage cloud Dropbox. Téléversez, téléchargez, organisez des fichiers et dossiers, gérez le partage et la collaboration, gérez les versions de fichiers, créez des demandes de fichiers et effectuez des opérations groupées sur vos fichiers et dossiers Dropbox.", + "tools.composio.servers.dropbox.readme": "Intégrez Dropbox pour accéder à vos fichiers et les gérer. Téléversez, téléchargez, partagez des fichiers, gérez des dossiers, gérez les versions de fichiers et organisez votre stockage cloud via l'IA conversationnelle.", + "tools.composio.servers.figma.description": "Figma est un outil collaboratif de conception d’interfaces pour les applications web et mobiles.", + "tools.composio.servers.figma.readme": "Connectez-vous à Figma pour accéder à vos fichiers de design et collaborer sur vos projets. Visualisez des maquettes, exportez des ressources, explorez des composants et gérez votre flux de travail de design via une conversation naturelle.", + "tools.composio.servers.github.description": "Serveur MCP GitHub amélioré", + "tools.composio.servers.github.readme": "Connectez-vous à GitHub pour gérer vos dépôts, problèmes, pull requests et code. Recherchez du code, examinez des modifications, créez des branches et collaborez sur des projets de développement logiciel via l'IA conversationnelle.", + "tools.composio.servers.gmail.description": "Gmail est un service de messagerie gratuit proposé par Google", + "tools.composio.servers.gmail.readme": "Profitez de la puissance de Gmail directement dans votre assistant IA. Lisez, rédigez et envoyez des e-mails, recherchez dans votre boîte de réception, gérez les libellés et organisez vos communications — le tout par conversation naturelle.", + "tools.composio.servers.google-calendar.description": "Google Agenda est un service de calendrier de gestion du temps et de planification", + "tools.composio.servers.google-calendar.readme": "Intégrez Google Agenda pour consulter, créer et gérer vos événements en toute fluidité. Planifiez des réunions, définissez des rappels, vérifiez les disponibilités et organisez votre emploi du temps via des commandes en langage naturel.", + "tools.composio.servers.google-docs.description": "Google Docs est un traitement de texte inclus dans la suite gratuite d’éditeurs Google Docs basée sur le web", + "tools.composio.servers.google-docs.readme": "Intégrez Google Docs pour créer, modifier et gérer vos documents. Rédigez du contenu, mettez en forme du texte, collaborez en temps réel et accédez à vos documents via une conversation naturelle.", + "tools.composio.servers.google-drive.description": "Google Drive est un service de stockage cloud", + "tools.composio.servers.google-drive.readme": "Connectez-vous à Google Drive pour accéder à vos fichiers, les organiser et les gérer. Recherchez des documents, téléversez des fichiers, partagez du contenu et naviguez efficacement dans votre stockage cloud grâce à l'assistance de l'IA.", + "tools.composio.servers.google-sheets.description": "Google Sheets est une application de tableur en ligne qui permet aux utilisateurs de créer, modifier et collaborer sur des feuilles de calcul", + "tools.composio.servers.google-sheets.readme": "Connectez-vous à Google Sheets pour lire, écrire et analyser des données de tableur. Effectuez des calculs, générez des rapports, créez des graphiques et gérez des données tabulaires en collaboration avec l'aide de l'IA.", + "tools.composio.servers.hubspot.description": "HubSpot est un éditeur de logiciels pour le marketing entrant, les ventes et le service client", + "tools.composio.servers.hubspot.readme": "Intégrez HubSpot pour gérer vos contacts, opportunités et campagnes marketing. Accédez aux données CRM, suivez les pipelines, automatisez les flux de travail et optimisez vos opérations commerciales et marketing.", + "tools.composio.servers.jira.description": "Jira est un outil de gestion de projet et de suivi des problèmes développé par Atlassian", + "tools.composio.servers.jira.readme": "Intégrez Jira pour gérer les tickets, suivre les progrès et organiser les sprints. Créez des tickets, mettez à jour les statuts, interrogez les données de projet et optimisez votre flux de développement via une conversation naturelle.", + "tools.composio.servers.notion.description": "Notion est une application collaborative de productivité et de prise de notes", + "tools.composio.servers.notion.readme": "Connectez-vous à Notion pour accéder à votre espace de travail et le gérer. Créez des pages, recherchez du contenu, mettez à jour des bases de données et organisez votre base de connaissances — le tout via une conversation naturelle avec votre assistant IA.", + "tools.composio.servers.onedrive.description": "OneDrive est un service d’hébergement et de synchronisation de fichiers opéré par Microsoft", + "tools.composio.servers.onedrive.readme": "Connectez-vous à OneDrive pour accéder à vos fichiers cloud Microsoft et les gérer. Téléversez, téléchargez, partagez des fichiers, organisez des dossiers et collaborez sur des documents grâce à l'assistance de l'IA.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail est une suite web de messagerie, contacts, tâches et calendrier proposée par Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Intégrez Outlook Mail pour lire, envoyer et gérer vos e-mails Microsoft. Recherchez des messages, rédigez des e-mails, gérez des dossiers et organisez votre boîte de réception via une conversation naturelle.", + "tools.composio.servers.salesforce.description": "Salesforce est la principale plateforme de gestion de la relation client (CRM) au monde, aidant les entreprises à se connecter avec leurs clients, partenaires et prospects", + "tools.composio.servers.salesforce.readme": "Connectez-vous à Salesforce pour gérer vos relations clients et données commerciales. Interrogez des enregistrements, mettez à jour des opportunités, suivez des prospects et automatisez vos flux CRM via des commandes en langage naturel.", + "tools.composio.servers.slack.description": "Slack est une application de messagerie professionnelle qui connecte les personnes aux informations dont elles ont besoin", + "tools.composio.servers.slack.readme": "Intégrez Slack pour envoyer des messages, rechercher des conversations et gérer des canaux. Restez connecté avec votre équipe, automatisez les communications et accédez aux informations de votre espace de travail via le langage naturel.", + "tools.composio.servers.supabase.description": "Serveur MCP officiel de Supabase", + "tools.composio.servers.supabase.readme": "Intégrez Supabase pour gérer votre base de données et vos services backend. Interrogez des données, gérez l'authentification, manipulez le stockage et interagissez avec votre backend applicatif via une conversation naturelle.", + "tools.composio.servers.whatsapp.description": "Intégration de l’API WhatsApp Business permettant l’envoi de messages texte, de médias et la gestion des conversations avec les clients. Parfait pour le support client, les campagnes marketing et les flux de messagerie automatisés via la plateforme officielle WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Intégrez WhatsApp Business pour envoyer des messages, gérer des conversations et interagir avec vos clients. Automatisez les flux de messagerie et gérez vos communications via l'IA conversationnelle.", + "tools.composio.servers.youtube.description": "YouTube est une plateforme de partage de vidéos où les utilisateurs peuvent téléverser, partager et découvrir du contenu. Accédez aux informations, transcriptions et métadonnées des vidéos de manière programmatique.", + "tools.composio.servers.youtube.readme": "Connectez-vous à YouTube pour rechercher des vidéos, accéder aux transcriptions et récupérer des informations. Analysez le contenu, extrayez des métadonnées et découvrez des vidéos via une conversation naturelle.", + "tools.composio.servers.zendesk.description": "Zendesk est une entreprise de logiciels de service client", + "tools.composio.servers.zendesk.readme": "Intégrez Zendesk pour gérer les tickets de support et les interactions clients. Créez, mettez à jour et suivez les demandes d'assistance, accédez aux données clients et optimisez vos opérations de support.", + "tools.composio.tools": "outils", + "tools.composio.verifyAuth": "J’ai terminé l’authentification", "tools.lobehubSkill.authorize": "Autoriser", "tools.lobehubSkill.connect": "Connecter", "tools.lobehubSkill.connected": "Connecté", diff --git a/locales/it-IT/setting.json b/locales/it-IT/setting.json index c9b093d6eb5..0780f9f994a 100644 --- a/locales/it-IT/setting.json +++ b/locales/it-IT/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Disinstalla {{name}}", "tools.builtins.uninstalled": "Disinstallato", "tools.disabled": "Il modello attuale non supporta le chiamate di funzione e non può utilizzare la competenza", - "tools.klavis.addServer": "Aggiungi Server", - "tools.klavis.authCompleted": "Autenticazione Completata", - "tools.klavis.authFailed": "Autenticazione Fallita", - "tools.klavis.authRequired": "Autenticazione Richiesta", - "tools.klavis.connect": "Connetti", - "tools.klavis.connected": "Connesso", - "tools.klavis.disconnect": "Disconnetti", - "tools.klavis.disconnected": "Disconnesso", - "tools.klavis.error": "Errore", - "tools.klavis.groupName": "Strumenti Klavis", - "tools.klavis.manage": "Gestisci Klavis", - "tools.klavis.manageTitle": "Gestione Integrazione Klavis", - "tools.klavis.noServers": "Nessun server connesso", - "tools.klavis.notEnabled": "Servizio Klavis non abilitato", - "tools.klavis.oauthRequired": "Completa l'autenticazione OAuth nella nuova finestra", - "tools.klavis.pendingAuth": "Autenticazione in Attesa", - "tools.klavis.remove": "Rimuovi", - "tools.klavis.removeConfirm.desc": "{{name}} sarà rimosso definitivamente dai tuoi servizi collegati. Questa azione non può essere annullata.", - "tools.klavis.removeConfirm.title": "Rimuovere {{name}}?", - "tools.klavis.serverCreated": "Server creato con successo", - "tools.klavis.serverCreatedFailed": "Creazione server fallita", - "tools.klavis.serverRemoved": "Server rimosso", - "tools.klavis.servers": "server", - "tools.klavis.servers.airtable.description": "Airtable è una piattaforma cloud che unisce la flessibilità di un foglio di calcolo con la potenza di un database, permettendo ai team di organizzare, monitorare e collaborare su progetti con viste personalizzabili e potenti funzionalità di automazione.", - "tools.klavis.servers.airtable.readme": "Integra con Airtable per gestire database e flussi di lavoro. Interroga record, crea voci, aggiorna dati e automatizza operazioni con viste personalizzabili e potenti funzionalità di tracciamento.", - "tools.klavis.servers.cal-com.description": "Cal.com è una piattaforma open-source per la pianificazione di appuntamenti che ti aiuta a organizzare incontri senza scambi di email. Gestisci tipi di eventi, prenotazioni, disponibilità e integra i calendari per una pianificazione fluida.", - "tools.klavis.servers.cal-com.readme": "Collegati a Cal.com per gestire la pianificazione e gli appuntamenti. Visualizza disponibilità, prenota riunioni, gestisci tipi di eventi e automatizza il calendario tramite conversazioni naturali.", - "tools.klavis.servers.clickup.description": "ClickUp è una piattaforma completa per la gestione dei progetti e la produttività, che aiuta i team a organizzare attività, gestire progetti e collaborare in modo efficace con flussi di lavoro personalizzabili e potenti strumenti di monitoraggio.", - "tools.klavis.servers.clickup.readme": "Connettiti a ClickUp per gestire attività, monitorare progetti e organizzare il lavoro. Crea attività, aggiorna stati, gestisci flussi di lavoro personalizzati e collabora con il tuo team tramite comandi in linguaggio naturale.", - "tools.klavis.servers.confluence.description": "Confluence è uno spazio di lavoro collaborativo dove si incontrano conoscenza e collaborazione.", - "tools.klavis.servers.confluence.readme": "Connettiti a Confluence per accedere e gestire la documentazione del team. Cerca pagine, crea contenuti, organizza spazi e costruisci la tua base di conoscenza con l'assistenza dell'IA conversazionale.", - "tools.klavis.servers.dropbox.description": "Soluzione completa per la gestione dei file su Dropbox. Carica, scarica, organizza file e cartelle, gestisci condivisioni e collaborazioni, versioni dei file, richieste di file e operazioni in batch.", - "tools.klavis.servers.dropbox.readme": "Integra con Dropbox per accedere e gestire i tuoi file. Carica, scarica, condividi file, gestisci cartelle, controlla le versioni e organizza l'archiviazione cloud tramite IA conversazionale.", - "tools.klavis.servers.figma.description": "Figma è uno strumento collaborativo per il design di interfacce web e mobile.", - "tools.klavis.servers.figma.readme": "Connettiti a Figma per accedere ai file di design e collaborare ai progetti. Visualizza design, esporta risorse, esplora componenti e gestisci il flusso di lavoro di design tramite conversazioni naturali.", - "tools.klavis.servers.github.description": "Server MCP GitHub avanzato", - "tools.klavis.servers.github.readme": "Connettiti a GitHub per gestire repository, issue, pull request e codice. Cerca codice, revisiona modifiche, crea branch e collabora a progetti di sviluppo software tramite IA conversazionale.", - "tools.klavis.servers.gmail.description": "Gmail è un servizio email gratuito offerto da Google", - "tools.klavis.servers.gmail.readme": "Porta la potenza di Gmail direttamente nel tuo assistente IA. Leggi, scrivi e invia email, cerca nella posta in arrivo, gestisci etichette e organizza le comunicazioni—tutto tramite conversazioni naturali.", - "tools.klavis.servers.google-calendar.description": "Google Calendar è un servizio di gestione del tempo e pianificazione", - "tools.klavis.servers.google-calendar.readme": "Integra Google Calendar per visualizzare, creare e gestire eventi senza interruzioni. Pianifica riunioni, imposta promemoria, controlla disponibilità e coordina il tuo tempo—tutto tramite comandi in linguaggio naturale.", - "tools.klavis.servers.google-docs.description": "Google Docs è un elaboratore di testi incluso nella suite gratuita Google Docs Editors", - "tools.klavis.servers.google-docs.readme": "Integra con Google Docs per creare, modificare e gestire documenti. Scrivi contenuti, formatta testo, collabora in tempo reale e accedi ai tuoi documenti tramite conversazioni naturali.", - "tools.klavis.servers.google-drive.description": "Google Drive è un servizio di archiviazione cloud", - "tools.klavis.servers.google-drive.readme": "Connettiti a Google Drive per accedere, organizzare e gestire i tuoi file. Cerca documenti, carica file, condividi contenuti e naviga nell'archiviazione cloud in modo efficiente con l'assistenza dell'IA.", - "tools.klavis.servers.google-sheets.description": "Google Sheets è un'applicazione di fogli di calcolo online che consente agli utenti di creare, modificare e collaborare su fogli di calcolo", - "tools.klavis.servers.google-sheets.readme": "Connettiti a Google Sheets per leggere, scrivere e analizzare dati in fogli di calcolo. Esegui calcoli, genera report, crea grafici e gestisci dati tabellari in collaborazione con l'assistenza dell'IA.", - "tools.klavis.servers.hubspot.description": "HubSpot sviluppa software per marketing inbound, vendite e assistenza clienti", - "tools.klavis.servers.hubspot.readme": "Integra con HubSpot per gestire contatti, trattative e campagne di marketing. Accedi ai dati CRM, monitora pipeline, automatizza flussi di lavoro e ottimizza le operazioni di vendita e marketing.", - "tools.klavis.servers.jira.description": "Jira è uno strumento per la gestione dei progetti e il tracciamento dei problemi sviluppato da Atlassian", - "tools.klavis.servers.jira.readme": "Integra con Jira per gestire issue, monitorare i progressi e organizzare sprint. Crea ticket, aggiorna stati, interroga dati di progetto e ottimizza il flusso di lavoro di sviluppo tramite conversazioni naturali.", - "tools.klavis.servers.notion.description": "Notion è un'applicazione collaborativa per la produttività e la gestione di appunti", - "tools.klavis.servers.notion.readme": "Connettiti a Notion per accedere e gestire il tuo spazio di lavoro. Crea pagine, cerca contenuti, aggiorna database e organizza la tua base di conoscenza—tutto tramite conversazioni naturali con il tuo assistente IA.", - "tools.klavis.servers.onedrive.description": "OneDrive è un servizio di hosting e sincronizzazione file gestito da Microsoft", - "tools.klavis.servers.onedrive.readme": "Connettiti a OneDrive per accedere e gestire i tuoi file cloud Microsoft. Carica, scarica, condividi file, organizza cartelle e collabora su documenti con l'assistenza dell'IA.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail è una suite web di posta elettronica, contatti, attività e calendario di Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Integra con Outlook Mail per leggere, inviare e gestire le tue email Microsoft. Cerca messaggi, scrivi email, gestisci cartelle e organizza la posta in arrivo tramite conversazioni naturali.", - "tools.klavis.servers.salesforce.description": "Salesforce è la principale piattaforma CRM al mondo che aiuta le aziende a connettersi con clienti, partner e potenziali clienti", - "tools.klavis.servers.salesforce.readme": "Connettiti a Salesforce per gestire relazioni con i clienti e dati di vendita. Interroga record, aggiorna opportunità, monitora lead e automatizza i flussi di lavoro CRM tramite comandi in linguaggio naturale.", - "tools.klavis.servers.slack.description": "Slack è un'app di messaggistica per il lavoro che connette le persone alle informazioni di cui hanno bisogno", - "tools.klavis.servers.slack.readme": "Integra con Slack per inviare messaggi, cercare conversazioni e gestire canali. Connettiti con il tuo team, automatizza i flussi di comunicazione e accedi alle informazioni dello spazio di lavoro tramite linguaggio naturale.", - "tools.klavis.servers.supabase.description": "Server MCP ufficiale di Supabase", - "tools.klavis.servers.supabase.readme": "Integra con Supabase per gestire il tuo database e i servizi backend. Interroga dati, gestisci autenticazioni, controlla l'archiviazione e interagisci con il backend della tua applicazione tramite conversazioni naturali.", - "tools.klavis.servers.whatsapp.description": "Integrazione con l'API WhatsApp Business che consente l'invio di messaggi di testo, media e la gestione delle conversazioni con i clienti. Ideale per supporto clienti, campagne marketing e flussi di messaggistica automatizzati tramite la piattaforma ufficiale.", - "tools.klavis.servers.whatsapp.readme": "Integra con WhatsApp Business per inviare messaggi, gestire conversazioni e interagire con i clienti. Automatizza i flussi di messaggistica e gestisci le comunicazioni tramite IA conversazionale.", - "tools.klavis.servers.youtube.description": "YouTube è una piattaforma di condivisione video dove gli utenti possono caricare, condividere e scoprire contenuti. Accedi a informazioni sui video, trascrizioni e metadati in modo programmatico.", - "tools.klavis.servers.youtube.readme": "Connettiti a YouTube per cercare video, accedere a trascrizioni e recuperare informazioni sui video. Analizza contenuti, estrai metadati e scopri video tramite conversazioni naturali.", - "tools.klavis.servers.zendesk.description": "Zendesk è un'azienda di software per il servizio clienti", - "tools.klavis.servers.zendesk.readme": "Integra con Zendesk per gestire ticket di supporto e interazioni con i clienti. Crea, aggiorna e monitora richieste di supporto, accedi ai dati dei clienti e ottimizza le operazioni di assistenza.", - "tools.klavis.tools": "strumenti", - "tools.klavis.verifyAuth": "Ho completato l'autenticazione", + "tools.composio.addServer": "Aggiungi Server", + "tools.composio.authCompleted": "Autenticazione Completata", + "tools.composio.authFailed": "Autenticazione Fallita", + "tools.composio.authRequired": "Autenticazione Richiesta", + "tools.composio.connect": "Connetti", + "tools.composio.connected": "Connesso", + "tools.composio.disconnect": "Disconnetti", + "tools.composio.disconnected": "Disconnesso", + "tools.composio.error": "Errore", + "tools.composio.groupName": "Strumenti Composio", + "tools.composio.manage": "Gestisci Composio", + "tools.composio.manageTitle": "Gestione Integrazione Composio", + "tools.composio.noServers": "Nessun server connesso", + "tools.composio.notEnabled": "Servizio Composio non abilitato", + "tools.composio.oauthRequired": "Completa l'autenticazione OAuth nella nuova finestra", + "tools.composio.pendingAuth": "Autenticazione in Attesa", + "tools.composio.serverCreated": "Server creato con successo", + "tools.composio.serverCreatedFailed": "Creazione server fallita", + "tools.composio.serverRemoved": "Server rimosso", + "tools.composio.servers": "server", + "tools.composio.servers.airtable.description": "Airtable è una piattaforma cloud che unisce la flessibilità di un foglio di calcolo con la potenza di un database, permettendo ai team di organizzare, monitorare e collaborare su progetti con viste personalizzabili e potenti funzionalità di automazione.", + "tools.composio.servers.airtable.readme": "Integra con Airtable per gestire database e flussi di lavoro. Interroga record, crea voci, aggiorna dati e automatizza operazioni con viste personalizzabili e potenti funzionalità di tracciamento.", + "tools.composio.servers.cal-com.description": "Cal.com è una piattaforma open-source per la pianificazione di appuntamenti che ti aiuta a organizzare incontri senza scambi di email. Gestisci tipi di eventi, prenotazioni, disponibilità e integra i calendari per una pianificazione fluida.", + "tools.composio.servers.cal-com.readme": "Collegati a Cal.com per gestire la pianificazione e gli appuntamenti. Visualizza disponibilità, prenota riunioni, gestisci tipi di eventi e automatizza il calendario tramite conversazioni naturali.", + "tools.composio.servers.clickup.description": "ClickUp è una piattaforma completa per la gestione dei progetti e la produttività, che aiuta i team a organizzare attività, gestire progetti e collaborare in modo efficace con flussi di lavoro personalizzabili e potenti strumenti di monitoraggio.", + "tools.composio.servers.clickup.readme": "Connettiti a ClickUp per gestire attività, monitorare progetti e organizzare il lavoro. Crea attività, aggiorna stati, gestisci flussi di lavoro personalizzati e collabora con il tuo team tramite comandi in linguaggio naturale.", + "tools.composio.servers.confluence.description": "Confluence è uno spazio di lavoro collaborativo dove si incontrano conoscenza e collaborazione.", + "tools.composio.servers.confluence.readme": "Connettiti a Confluence per accedere e gestire la documentazione del team. Cerca pagine, crea contenuti, organizza spazi e costruisci la tua base di conoscenza con l'assistenza dell'IA conversazionale.", + "tools.composio.servers.dropbox.description": "Soluzione completa per la gestione dei file su Dropbox. Carica, scarica, organizza file e cartelle, gestisci condivisioni e collaborazioni, versioni dei file, richieste di file e operazioni in batch.", + "tools.composio.servers.dropbox.readme": "Integra con Dropbox per accedere e gestire i tuoi file. Carica, scarica, condividi file, gestisci cartelle, controlla le versioni e organizza l'archiviazione cloud tramite IA conversazionale.", + "tools.composio.servers.figma.description": "Figma è uno strumento collaborativo per il design di interfacce web e mobile.", + "tools.composio.servers.figma.readme": "Connettiti a Figma per accedere ai file di design e collaborare ai progetti. Visualizza design, esporta risorse, esplora componenti e gestisci il flusso di lavoro di design tramite conversazioni naturali.", + "tools.composio.servers.github.description": "Server MCP GitHub avanzato", + "tools.composio.servers.github.readme": "Connettiti a GitHub per gestire repository, issue, pull request e codice. Cerca codice, revisiona modifiche, crea branch e collabora a progetti di sviluppo software tramite IA conversazionale.", + "tools.composio.servers.gmail.description": "Gmail è un servizio email gratuito offerto da Google", + "tools.composio.servers.gmail.readme": "Porta la potenza di Gmail direttamente nel tuo assistente IA. Leggi, scrivi e invia email, cerca nella posta in arrivo, gestisci etichette e organizza le comunicazioni—tutto tramite conversazioni naturali.", + "tools.composio.servers.google-calendar.description": "Google Calendar è un servizio di gestione del tempo e pianificazione", + "tools.composio.servers.google-calendar.readme": "Integra Google Calendar per visualizzare, creare e gestire eventi senza interruzioni. Pianifica riunioni, imposta promemoria, controlla disponibilità e coordina il tuo tempo—tutto tramite comandi in linguaggio naturale.", + "tools.composio.servers.google-docs.description": "Google Docs è un elaboratore di testi incluso nella suite gratuita Google Docs Editors", + "tools.composio.servers.google-docs.readme": "Integra con Google Docs per creare, modificare e gestire documenti. Scrivi contenuti, formatta testo, collabora in tempo reale e accedi ai tuoi documenti tramite conversazioni naturali.", + "tools.composio.servers.google-drive.description": "Google Drive è un servizio di archiviazione cloud", + "tools.composio.servers.google-drive.readme": "Connettiti a Google Drive per accedere, organizzare e gestire i tuoi file. Cerca documenti, carica file, condividi contenuti e naviga nell'archiviazione cloud in modo efficiente con l'assistenza dell'IA.", + "tools.composio.servers.google-sheets.description": "Google Sheets è un'applicazione di fogli di calcolo online che consente agli utenti di creare, modificare e collaborare su fogli di calcolo", + "tools.composio.servers.google-sheets.readme": "Connettiti a Google Sheets per leggere, scrivere e analizzare dati in fogli di calcolo. Esegui calcoli, genera report, crea grafici e gestisci dati tabellari in collaborazione con l'assistenza dell'IA.", + "tools.composio.servers.hubspot.description": "HubSpot sviluppa software per marketing inbound, vendite e assistenza clienti", + "tools.composio.servers.hubspot.readme": "Integra con HubSpot per gestire contatti, trattative e campagne di marketing. Accedi ai dati CRM, monitora pipeline, automatizza flussi di lavoro e ottimizza le operazioni di vendita e marketing.", + "tools.composio.servers.jira.description": "Jira è uno strumento per la gestione dei progetti e il tracciamento dei problemi sviluppato da Atlassian", + "tools.composio.servers.jira.readme": "Integra con Jira per gestire issue, monitorare i progressi e organizzare sprint. Crea ticket, aggiorna stati, interroga dati di progetto e ottimizza il flusso di lavoro di sviluppo tramite conversazioni naturali.", + "tools.composio.servers.notion.description": "Notion è un'applicazione collaborativa per la produttività e la gestione di appunti", + "tools.composio.servers.notion.readme": "Connettiti a Notion per accedere e gestire il tuo spazio di lavoro. Crea pagine, cerca contenuti, aggiorna database e organizza la tua base di conoscenza—tutto tramite conversazioni naturali con il tuo assistente IA.", + "tools.composio.servers.onedrive.description": "OneDrive è un servizio di hosting e sincronizzazione file gestito da Microsoft", + "tools.composio.servers.onedrive.readme": "Connettiti a OneDrive per accedere e gestire i tuoi file cloud Microsoft. Carica, scarica, condividi file, organizza cartelle e collabora su documenti con l'assistenza dell'IA.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail è una suite web di posta elettronica, contatti, attività e calendario di Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Integra con Outlook Mail per leggere, inviare e gestire le tue email Microsoft. Cerca messaggi, scrivi email, gestisci cartelle e organizza la posta in arrivo tramite conversazioni naturali.", + "tools.composio.servers.salesforce.description": "Salesforce è la principale piattaforma CRM al mondo che aiuta le aziende a connettersi con clienti, partner e potenziali clienti", + "tools.composio.servers.salesforce.readme": "Connettiti a Salesforce per gestire relazioni con i clienti e dati di vendita. Interroga record, aggiorna opportunità, monitora lead e automatizza i flussi di lavoro CRM tramite comandi in linguaggio naturale.", + "tools.composio.servers.slack.description": "Slack è un'app di messaggistica per il lavoro che connette le persone alle informazioni di cui hanno bisogno", + "tools.composio.servers.slack.readme": "Integra con Slack per inviare messaggi, cercare conversazioni e gestire canali. Connettiti con il tuo team, automatizza i flussi di comunicazione e accedi alle informazioni dello spazio di lavoro tramite linguaggio naturale.", + "tools.composio.servers.supabase.description": "Server MCP ufficiale di Supabase", + "tools.composio.servers.supabase.readme": "Integra con Supabase per gestire il tuo database e i servizi backend. Interroga dati, gestisci autenticazioni, controlla l'archiviazione e interagisci con il backend della tua applicazione tramite conversazioni naturali.", + "tools.composio.servers.whatsapp.description": "Integrazione con l'API WhatsApp Business che consente l'invio di messaggi di testo, media e la gestione delle conversazioni con i clienti. Ideale per supporto clienti, campagne marketing e flussi di messaggistica automatizzati tramite la piattaforma ufficiale.", + "tools.composio.servers.whatsapp.readme": "Integra con WhatsApp Business per inviare messaggi, gestire conversazioni e interagire con i clienti. Automatizza i flussi di messaggistica e gestisci le comunicazioni tramite IA conversazionale.", + "tools.composio.servers.youtube.description": "YouTube è una piattaforma di condivisione video dove gli utenti possono caricare, condividere e scoprire contenuti. Accedi a informazioni sui video, trascrizioni e metadati in modo programmatico.", + "tools.composio.servers.youtube.readme": "Connettiti a YouTube per cercare video, accedere a trascrizioni e recuperare informazioni sui video. Analizza contenuti, estrai metadati e scopri video tramite conversazioni naturali.", + "tools.composio.servers.zendesk.description": "Zendesk è un'azienda di software per il servizio clienti", + "tools.composio.servers.zendesk.readme": "Integra con Zendesk per gestire ticket di supporto e interazioni con i clienti. Crea, aggiorna e monitora richieste di supporto, accedi ai dati dei clienti e ottimizza le operazioni di assistenza.", + "tools.composio.tools": "strumenti", + "tools.composio.verifyAuth": "Ho completato l'autenticazione", "tools.lobehubSkill.authorize": "Autorizza", "tools.lobehubSkill.connect": "Connetti", "tools.lobehubSkill.connected": "Connesso", diff --git a/locales/ja-JP/setting.json b/locales/ja-JP/setting.json index 5729c06f9d8..edc9ddf88e9 100644 --- a/locales/ja-JP/setting.json +++ b/locales/ja-JP/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "{{name}} のアンインストール", "tools.builtins.uninstalled": "アンインストール済み", "tools.disabled": "現在のモデルは関数呼び出しをサポートしていません。スキルを使用できません", - "tools.klavis.addServer": "サーバーを追加", - "tools.klavis.authCompleted": "認証完了", - "tools.klavis.authFailed": "認証に失敗しました", - "tools.klavis.authRequired": "認証が必要です", - "tools.klavis.connect": "接続", - "tools.klavis.connected": "接続済み", - "tools.klavis.disconnect": "切断する", - "tools.klavis.disconnected": "未接続", - "tools.klavis.error": "エラー", - "tools.klavis.groupName": "Klavis ツール", - "tools.klavis.manage": "Klavis を管理", - "tools.klavis.manageTitle": "Klavis 統合を管理", - "tools.klavis.noServers": "接続されているサーバーはありません", - "tools.klavis.notEnabled": "Klavis サービスは有効化されていません", - "tools.klavis.oauthRequired": "新しいウィンドウで OAuth 認証を完了してください", - "tools.klavis.pendingAuth": "認証待ち", - "tools.klavis.remove": "削除", - "tools.klavis.removeConfirm.desc": "{{name}}は接続されたサービスから永久に削除されます。この操作は元に戻すことができません。", - "tools.klavis.removeConfirm.title": "{{name}}を削除しますか?", - "tools.klavis.serverCreated": "サーバーが正常に作成されました", - "tools.klavis.serverCreatedFailed": "サーバーの作成に失敗しました", - "tools.klavis.serverRemoved": "サーバーが削除されました", - "tools.klavis.servers": "台のサーバー", - "tools.klavis.servers.airtable.description": "Airtableは、スプレッドシートの柔軟性とデータベースの強力さを兼ね備えたクラウドベースのデータベース&スプレッドシートプラットフォームで、チームがプロジェクトを整理・追跡・共同作業できるようにします。", - "tools.klavis.servers.airtable.readme": "Airtableと連携してデータベースやワークフローを管理します。レコードの検索、エントリの作成、データの更新、カスタマイズ可能なビューと強力なトラッキング機能による自動化が可能です。", - "tools.klavis.servers.cal-com.description": "Cal.comは、メールのやり取りなしでミーティングのスケジュールを調整できるオープンソースのスケジューリングプラットフォームです。イベントタイプ、予約、空き状況の管理やカレンダーとの連携が可能です。", - "tools.klavis.servers.cal-com.readme": "Cal.comと接続してスケジュールや予定を管理します。空き状況の確認、会議の予約、イベントタイプの管理、自然な会話を通じたカレンダーの自動化が可能です。", - "tools.klavis.servers.clickup.description": "ClickUpは、タスクの整理、プロジェクト管理、チームの効果的なコラボレーションを支援する包括的なプロジェクト管理・生産性向上プラットフォームです。", - "tools.klavis.servers.clickup.readme": "ClickUpと連携してタスク管理、プロジェクトの進捗追跡、作業の整理を行います。タスクの作成、ステータスの更新、カスタムワークフローの管理、チームとの自然言語によるコラボレーションが可能です。", - "tools.klavis.servers.confluence.description": "Confluenceは、知識とコラボレーションが融合するチームワークスペースです。", - "tools.klavis.servers.confluence.readme": "Confluenceと接続してチームドキュメントにアクセス・管理します。ページの検索、コンテンツの作成、スペースの整理、会話型AIによるナレッジベースの構築が可能です。", - "tools.klavis.servers.dropbox.description": "Dropboxのクラウドストレージにおける完全なファイル管理ソリューション。ファイルやフォルダのアップロード、ダウンロード、整理、共有管理、バージョン管理、ファイルリクエストの作成、バッチ操作が可能です。", - "tools.klavis.servers.dropbox.readme": "Dropboxと連携してファイルにアクセス・管理します。ファイルのアップロード、ダウンロード、共有、フォルダ管理、バージョン管理、クラウドストレージの整理を会話型AIで行えます。", - "tools.klavis.servers.figma.description": "Figmaは、Webおよびモバイルアプリ向けの共同インターフェースデザインツールです。", - "tools.klavis.servers.figma.readme": "Figmaと接続してデザインファイルにアクセスし、プロジェクトで共同作業を行います。デザインの閲覧、アセットのエクスポート、コンポーネントの閲覧、自然な会話によるデザインワークフローの管理が可能です。", - "tools.klavis.servers.github.description": "強化されたGitHub MCPサーバー", - "tools.klavis.servers.github.readme": "GitHubと連携してリポジトリ、イシュー、プルリクエスト、コードを管理します。コードの検索、変更のレビュー、ブランチの作成、会話型AIによるソフトウェア開発の共同作業が可能です。", - "tools.klavis.servers.gmail.description": "GmailはGoogleが提供する無料の電子メールサービスです。", - "tools.klavis.servers.gmail.readme": "Gmailの機能をAIアシスタントに統合します。メールの読み取り、作成、送信、受信トレイの検索、ラベルの管理、自然な会話によるコミュニケーションの整理が可能です。", - "tools.klavis.servers.google-calendar.description": "Google カレンダーは、時間管理とスケジューリングのためのカレンダーサービスです。", - "tools.klavis.servers.google-calendar.readme": "Googleカレンダーと連携してイベントの表示、作成、管理をシームレスに行います。会議のスケジューリング、リマインダーの設定、空き時間の確認、自然言語による時間調整が可能です。", - "tools.klavis.servers.google-docs.description": "Google ドキュメントは、Google ドキュメント エディタ スイートの一部である無料のWebベースのワープロです。", - "tools.klavis.servers.google-docs.readme": "Googleドキュメントと連携して文書の作成、編集、管理を行います。コンテンツの執筆、テキストの整形、リアルタイムでの共同作業、自然な会話によるドキュメントアクセスが可能です。", - "tools.klavis.servers.google-drive.description": "Google ドライブはクラウドストレージサービスです。", - "tools.klavis.servers.google-drive.readme": "Googleドライブと接続してファイルにアクセス、整理、管理します。ドキュメントの検索、ファイルのアップロード、コンテンツの共有、AIによるクラウドストレージの効率的な操作が可能です。", - "tools.klavis.servers.google-sheets.description": "Google スプレッドシートは、オンラインでスプレッドシートを作成・編集・共同作業できるWebベースのアプリケーションです。", - "tools.klavis.servers.google-sheets.readme": "Googleスプレッドシートと連携して表計算データの読み取り、書き込み、分析を行います。計算の実行、レポートの作成、チャートの生成、AIによる共同作業が可能です。", - "tools.klavis.servers.hubspot.description": "HubSpotは、インバウンドマーケティング、営業、カスタマーサービス向けのソフトウェアを開発・提供する企業です。", - "tools.klavis.servers.hubspot.readme": "HubSpotと連携してコンタクト、商談、マーケティングキャンペーンを管理します。CRMデータへのアクセス、パイプラインの追跡、ワークフローの自動化、営業・マーケティング業務の効率化が可能です。", - "tools.klavis.servers.jira.description": "Jiraは、Atlassianが開発したプロジェクト管理および課題追跡ツールです。", - "tools.klavis.servers.jira.readme": "Jiraと連携してイシューの管理、進捗の追跡、スプリントの整理を行います。チケットの作成、ステータスの更新、プロジェクトデータの検索、自然な会話による開発ワークフローの最適化が可能です。", - "tools.klavis.servers.notion.description": "Notionは、共同作業とメモ作成のための生産性アプリケーションです。", - "tools.klavis.servers.notion.readme": "Notionと接続してワークスペースにアクセス・管理します。ページの作成、コンテンツの検索、データベースの更新、AIアシスタントとの自然な会話によるナレッジベースの整理が可能です。", - "tools.klavis.servers.onedrive.description": "OneDriveは、Microsoftが提供するファイルホスティングおよび同期サービスです。", - "tools.klavis.servers.onedrive.readme": "OneDriveと連携してMicrosoftクラウドファイルにアクセス・管理します。ファイルのアップロード、ダウンロード、共有、フォルダの整理、AIによるドキュメントの共同作業が可能です。", - "tools.klavis.servers.outlook-mail.description": "Outlook Mailは、Microsoftが提供するWebメール、連絡先、タスク、カレンダーサービスの統合スイートです。", - "tools.klavis.servers.outlook-mail.readme": "Outlookメールと連携してMicrosoftのメールを読み取り、送信、管理します。メッセージの検索、メールの作成、フォルダの管理、自然な会話による受信トレイの整理が可能です。", - "tools.klavis.servers.salesforce.description": "Salesforceは、世界をリードする顧客関係管理(CRM)プラットフォームで、企業が顧客、パートナー、見込み客とつながるのを支援します。", - "tools.klavis.servers.salesforce.readme": "Salesforceと接続して顧客関係と営業データを管理します。レコードの検索、商談の更新、リードの追跡、CRMワークフローの自然言語による自動化が可能です。", - "tools.klavis.servers.slack.description": "Slackは、必要な情報に人々をつなぐビジネス向けメッセージングアプリです。", - "tools.klavis.servers.slack.readme": "Slackと連携してメッセージの送信、会話の検索、チャンネルの管理を行います。チームとの連携、コミュニケーションワークフローの自動化、ワークスペース情報へのアクセスが可能です。", - "tools.klavis.servers.supabase.description": "Supabase公式MCPサーバー", - "tools.klavis.servers.supabase.readme": "Supabaseと連携してデータベースやバックエンドサービスを管理します。データのクエリ、認証の管理、ストレージの操作、自然な会話によるアプリケーションバックエンドとの連携が可能です。", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business APIとの統合により、テキストメッセージやメディアの送信、顧客との会話管理が可能になります。カスタマーサポート、マーケティングキャンペーン、自動メッセージングワークフローに最適です。", - "tools.klavis.servers.whatsapp.readme": "WhatsApp Businessと連携してメッセージの送信、会話の管理、顧客とのやり取りを行います。メッセージングワークフローの自動化、会話型AIによるコミュニケーションの処理が可能です。", - "tools.klavis.servers.youtube.description": "YouTubeは、ユーザーが動画をアップロード、共有、発見できる動画共有プラットフォームです。動画情報、字幕、メタデータにプログラム的にアクセスできます。", - "tools.klavis.servers.youtube.readme": "YouTubeと接続して動画の検索、トランスクリプトの取得、動画情報へのアクセスを行います。コンテンツの分析、メタデータの抽出、自然な会話による動画の発見が可能です。", - "tools.klavis.servers.zendesk.description": "Zendeskはカスタマーサービス向けのソフトウェア企業です。", - "tools.klavis.servers.zendesk.readme": "Zendeskと連携してサポートチケットや顧客対応を管理します。サポートリクエストの作成、更新、追跡、顧客データへのアクセス、サポート業務の効率化が可能です。", - "tools.klavis.tools": "個のツール", - "tools.klavis.verifyAuth": "認証を完了しました", + "tools.composio.addServer": "サーバーを追加", + "tools.composio.authCompleted": "認証完了", + "tools.composio.authFailed": "認証に失敗しました", + "tools.composio.authRequired": "認証が必要です", + "tools.composio.connect": "接続", + "tools.composio.connected": "接続済み", + "tools.composio.disconnect": "切断する", + "tools.composio.disconnected": "未接続", + "tools.composio.error": "エラー", + "tools.composio.groupName": "Composio ツール", + "tools.composio.manage": "Composio を管理", + "tools.composio.manageTitle": "Composio 統合を管理", + "tools.composio.noServers": "接続されているサーバーはありません", + "tools.composio.notEnabled": "Composio サービスは有効化されていません", + "tools.composio.oauthRequired": "新しいウィンドウで OAuth 認証を完了してください", + "tools.composio.pendingAuth": "認証待ち", + "tools.composio.serverCreated": "サーバーが正常に作成されました", + "tools.composio.serverCreatedFailed": "サーバーの作成に失敗しました", + "tools.composio.serverRemoved": "サーバーが削除されました", + "tools.composio.servers": "台のサーバー", + "tools.composio.servers.airtable.description": "Airtableは、スプレッドシートの柔軟性とデータベースの強力さを兼ね備えたクラウドベースのデータベース&スプレッドシートプラットフォームで、チームがプロジェクトを整理・追跡・共同作業できるようにします。", + "tools.composio.servers.airtable.readme": "Airtableと連携してデータベースやワークフローを管理します。レコードの検索、エントリの作成、データの更新、カスタマイズ可能なビューと強力なトラッキング機能による自動化が可能です。", + "tools.composio.servers.cal-com.description": "Cal.comは、メールのやり取りなしでミーティングのスケジュールを調整できるオープンソースのスケジューリングプラットフォームです。イベントタイプ、予約、空き状況の管理やカレンダーとの連携が可能です。", + "tools.composio.servers.cal-com.readme": "Cal.comと接続してスケジュールや予定を管理します。空き状況の確認、会議の予約、イベントタイプの管理、自然な会話を通じたカレンダーの自動化が可能です。", + "tools.composio.servers.clickup.description": "ClickUpは、タスクの整理、プロジェクト管理、チームの効果的なコラボレーションを支援する包括的なプロジェクト管理・生産性向上プラットフォームです。", + "tools.composio.servers.clickup.readme": "ClickUpと連携してタスク管理、プロジェクトの進捗追跡、作業の整理を行います。タスクの作成、ステータスの更新、カスタムワークフローの管理、チームとの自然言語によるコラボレーションが可能です。", + "tools.composio.servers.confluence.description": "Confluenceは、知識とコラボレーションが融合するチームワークスペースです。", + "tools.composio.servers.confluence.readme": "Confluenceと接続してチームドキュメントにアクセス・管理します。ページの検索、コンテンツの作成、スペースの整理、会話型AIによるナレッジベースの構築が可能です。", + "tools.composio.servers.dropbox.description": "Dropboxのクラウドストレージにおける完全なファイル管理ソリューション。ファイルやフォルダのアップロード、ダウンロード、整理、共有管理、バージョン管理、ファイルリクエストの作成、バッチ操作が可能です。", + "tools.composio.servers.dropbox.readme": "Dropboxと連携してファイルにアクセス・管理します。ファイルのアップロード、ダウンロード、共有、フォルダ管理、バージョン管理、クラウドストレージの整理を会話型AIで行えます。", + "tools.composio.servers.figma.description": "Figmaは、Webおよびモバイルアプリ向けの共同インターフェースデザインツールです。", + "tools.composio.servers.figma.readme": "Figmaと接続してデザインファイルにアクセスし、プロジェクトで共同作業を行います。デザインの閲覧、アセットのエクスポート、コンポーネントの閲覧、自然な会話によるデザインワークフローの管理が可能です。", + "tools.composio.servers.github.description": "強化されたGitHub MCPサーバー", + "tools.composio.servers.github.readme": "GitHubと連携してリポジトリ、イシュー、プルリクエスト、コードを管理します。コードの検索、変更のレビュー、ブランチの作成、会話型AIによるソフトウェア開発の共同作業が可能です。", + "tools.composio.servers.gmail.description": "GmailはGoogleが提供する無料の電子メールサービスです。", + "tools.composio.servers.gmail.readme": "Gmailの機能をAIアシスタントに統合します。メールの読み取り、作成、送信、受信トレイの検索、ラベルの管理、自然な会話によるコミュニケーションの整理が可能です。", + "tools.composio.servers.google-calendar.description": "Google カレンダーは、時間管理とスケジューリングのためのカレンダーサービスです。", + "tools.composio.servers.google-calendar.readme": "Googleカレンダーと連携してイベントの表示、作成、管理をシームレスに行います。会議のスケジューリング、リマインダーの設定、空き時間の確認、自然言語による時間調整が可能です。", + "tools.composio.servers.google-docs.description": "Google ドキュメントは、Google ドキュメント エディタ スイートの一部である無料のWebベースのワープロです。", + "tools.composio.servers.google-docs.readme": "Googleドキュメントと連携して文書の作成、編集、管理を行います。コンテンツの執筆、テキストの整形、リアルタイムでの共同作業、自然な会話によるドキュメントアクセスが可能です。", + "tools.composio.servers.google-drive.description": "Google ドライブはクラウドストレージサービスです。", + "tools.composio.servers.google-drive.readme": "Googleドライブと接続してファイルにアクセス、整理、管理します。ドキュメントの検索、ファイルのアップロード、コンテンツの共有、AIによるクラウドストレージの効率的な操作が可能です。", + "tools.composio.servers.google-sheets.description": "Google スプレッドシートは、オンラインでスプレッドシートを作成・編集・共同作業できるWebベースのアプリケーションです。", + "tools.composio.servers.google-sheets.readme": "Googleスプレッドシートと連携して表計算データの読み取り、書き込み、分析を行います。計算の実行、レポートの作成、チャートの生成、AIによる共同作業が可能です。", + "tools.composio.servers.hubspot.description": "HubSpotは、インバウンドマーケティング、営業、カスタマーサービス向けのソフトウェアを開発・提供する企業です。", + "tools.composio.servers.hubspot.readme": "HubSpotと連携してコンタクト、商談、マーケティングキャンペーンを管理します。CRMデータへのアクセス、パイプラインの追跡、ワークフローの自動化、営業・マーケティング業務の効率化が可能です。", + "tools.composio.servers.jira.description": "Jiraは、Atlassianが開発したプロジェクト管理および課題追跡ツールです。", + "tools.composio.servers.jira.readme": "Jiraと連携してイシューの管理、進捗の追跡、スプリントの整理を行います。チケットの作成、ステータスの更新、プロジェクトデータの検索、自然な会話による開発ワークフローの最適化が可能です。", + "tools.composio.servers.notion.description": "Notionは、共同作業とメモ作成のための生産性アプリケーションです。", + "tools.composio.servers.notion.readme": "Notionと接続してワークスペースにアクセス・管理します。ページの作成、コンテンツの検索、データベースの更新、AIアシスタントとの自然な会話によるナレッジベースの整理が可能です。", + "tools.composio.servers.onedrive.description": "OneDriveは、Microsoftが提供するファイルホスティングおよび同期サービスです。", + "tools.composio.servers.onedrive.readme": "OneDriveと連携してMicrosoftクラウドファイルにアクセス・管理します。ファイルのアップロード、ダウンロード、共有、フォルダの整理、AIによるドキュメントの共同作業が可能です。", + "tools.composio.servers.outlook-mail.description": "Outlook Mailは、Microsoftが提供するWebメール、連絡先、タスク、カレンダーサービスの統合スイートです。", + "tools.composio.servers.outlook-mail.readme": "Outlookメールと連携してMicrosoftのメールを読み取り、送信、管理します。メッセージの検索、メールの作成、フォルダの管理、自然な会話による受信トレイの整理が可能です。", + "tools.composio.servers.salesforce.description": "Salesforceは、世界をリードする顧客関係管理(CRM)プラットフォームで、企業が顧客、パートナー、見込み客とつながるのを支援します。", + "tools.composio.servers.salesforce.readme": "Salesforceと接続して顧客関係と営業データを管理します。レコードの検索、商談の更新、リードの追跡、CRMワークフローの自然言語による自動化が可能です。", + "tools.composio.servers.slack.description": "Slackは、必要な情報に人々をつなぐビジネス向けメッセージングアプリです。", + "tools.composio.servers.slack.readme": "Slackと連携してメッセージの送信、会話の検索、チャンネルの管理を行います。チームとの連携、コミュニケーションワークフローの自動化、ワークスペース情報へのアクセスが可能です。", + "tools.composio.servers.supabase.description": "Supabase公式MCPサーバー", + "tools.composio.servers.supabase.readme": "Supabaseと連携してデータベースやバックエンドサービスを管理します。データのクエリ、認証の管理、ストレージの操作、自然な会話によるアプリケーションバックエンドとの連携が可能です。", + "tools.composio.servers.whatsapp.description": "WhatsApp Business APIとの統合により、テキストメッセージやメディアの送信、顧客との会話管理が可能になります。カスタマーサポート、マーケティングキャンペーン、自動メッセージングワークフローに最適です。", + "tools.composio.servers.whatsapp.readme": "WhatsApp Businessと連携してメッセージの送信、会話の管理、顧客とのやり取りを行います。メッセージングワークフローの自動化、会話型AIによるコミュニケーションの処理が可能です。", + "tools.composio.servers.youtube.description": "YouTubeは、ユーザーが動画をアップロード、共有、発見できる動画共有プラットフォームです。動画情報、字幕、メタデータにプログラム的にアクセスできます。", + "tools.composio.servers.youtube.readme": "YouTubeと接続して動画の検索、トランスクリプトの取得、動画情報へのアクセスを行います。コンテンツの分析、メタデータの抽出、自然な会話による動画の発見が可能です。", + "tools.composio.servers.zendesk.description": "Zendeskはカスタマーサービス向けのソフトウェア企業です。", + "tools.composio.servers.zendesk.readme": "Zendeskと連携してサポートチケットや顧客対応を管理します。サポートリクエストの作成、更新、追跡、顧客データへのアクセス、サポート業務の効率化が可能です。", + "tools.composio.tools": "個のツール", + "tools.composio.verifyAuth": "認証を完了しました", "tools.lobehubSkill.authorize": "認証する", "tools.lobehubSkill.connect": "接続する", "tools.lobehubSkill.connected": "接続済み", diff --git a/locales/ko-KR/setting.json b/locales/ko-KR/setting.json index 2bf02fb390c..c9b47a4da81 100644 --- a/locales/ko-KR/setting.json +++ b/locales/ko-KR/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "{{name}} 제거", "tools.builtins.uninstalled": "제거됨", "tools.disabled": "현재 모델은 함수 호출을 지원하지 않으며 기능을 사용할 수 없습니다", - "tools.klavis.addServer": "서버 추가", - "tools.klavis.authCompleted": "인증 완료", - "tools.klavis.authFailed": "인증 실패", - "tools.klavis.authRequired": "인증 필요", - "tools.klavis.connect": "연결", - "tools.klavis.connected": "연결됨", - "tools.klavis.disconnect": "연결 해제", - "tools.klavis.disconnected": "연결 끊김", - "tools.klavis.error": "오류", - "tools.klavis.groupName": "Klavis 도구", - "tools.klavis.manage": "Klavis 관리", - "tools.klavis.manageTitle": "Klavis 통합 관리", - "tools.klavis.noServers": "연결된 서버 없음", - "tools.klavis.notEnabled": "Klavis 서비스가 활성화되지 않음", - "tools.klavis.oauthRequired": "새 창에서 OAuth 인증을 완료해 주세요", - "tools.klavis.pendingAuth": "인증 대기 중", - "tools.klavis.remove": "제거", - "tools.klavis.removeConfirm.desc": "{{name}}이(가) 연결된 서비스에서 영구적으로 제거됩니다. 이 작업은 되돌릴 수 없습니다.", - "tools.klavis.removeConfirm.title": "{{name}}을(를) 제거하시겠습니까?", - "tools.klavis.serverCreated": "서버 생성 성공", - "tools.klavis.serverCreatedFailed": "서버 생성 실패", - "tools.klavis.serverRemoved": "서버 삭제됨", - "tools.klavis.servers": "개의 서버", - "tools.klavis.servers.airtable.description": "Airtable은 스프레드시트의 유연성과 데이터베이스의 강력함을 결합한 클라우드 기반 데이터베이스 및 스프레드시트 플랫폼으로, 팀이 프로젝트를 체계적으로 관리하고 협업할 수 있도록 지원합니다.", - "tools.klavis.servers.airtable.readme": "Airtable과 통합하여 데이터베이스와 워크플로우를 관리하세요. 레코드 조회, 항목 생성, 데이터 업데이트, 사용자 정의 뷰와 강력한 추적 기능으로 작업을 자동화할 수 있습니다.", - "tools.klavis.servers.cal-com.description": "Cal.com은 이메일을 주고받지 않고도 회의를 예약할 수 있도록 도와주는 오픈소스 일정 관리 플랫폼입니다. 이벤트 유형, 예약, 가용성 관리 및 캘린더 통합이 가능합니다.", - "tools.klavis.servers.cal-com.readme": "Cal.com과 연결하여 일정과 약속을 관리하세요. 가용 시간 확인, 미팅 예약, 이벤트 유형 관리, 자연어 대화를 통한 캘린더 자동화가 가능합니다.", - "tools.klavis.servers.clickup.description": "ClickUp은 프로젝트 관리와 생산성을 위한 종합 플랫폼으로, 팀이 작업을 체계적으로 정리하고 협업할 수 있도록 지원합니다.", - "tools.klavis.servers.clickup.readme": "ClickUp과 연결하여 작업을 관리하고 프로젝트를 추적하며 업무를 체계화하세요. 작업 생성, 상태 업데이트, 맞춤형 워크플로우 관리, 팀과의 협업이 자연어 명령으로 가능합니다.", - "tools.klavis.servers.confluence.description": "Confluence는 지식과 협업이 만나는 팀 워크스페이스입니다.", - "tools.klavis.servers.confluence.readme": "Confluence와 연결하여 팀 문서를 접근하고 관리하세요. 페이지 검색, 콘텐츠 생성, 공간 구성, 대화형 AI 지원으로 지식 베이스를 구축할 수 있습니다.", - "tools.klavis.servers.dropbox.description": "Dropbox 클라우드 스토리지를 위한 완전한 파일 관리 솔루션입니다. 파일 및 폴더 업로드, 다운로드, 정리, 공유 및 협업 관리, 버전 관리, 파일 요청 생성, 일괄 작업 수행이 가능합니다.", - "tools.klavis.servers.dropbox.readme": "Dropbox와 통합하여 파일에 접근하고 관리하세요. 파일 업로드, 다운로드, 공유, 폴더 관리, 버전 제어, 클라우드 저장소 정리를 대화형 AI로 수행할 수 있습니다.", - "tools.klavis.servers.figma.description": "Figma는 웹 및 모바일 애플리케이션을 위한 협업 인터페이스 디자인 도구입니다.", - "tools.klavis.servers.figma.readme": "Figma와 연결하여 디자인 파일에 접근하고 프로젝트에 협업하세요. 디자인 보기, 에셋 내보내기, 구성 요소 탐색, 자연어 대화를 통한 디자인 워크플로우 관리가 가능합니다.", - "tools.klavis.servers.github.description": "향상된 GitHub MCP 서버", - "tools.klavis.servers.github.readme": "GitHub와 연결하여 저장소, 이슈, 풀 리퀘스트, 코드를 관리하세요. 코드 검색, 변경 사항 검토, 브랜치 생성, 소프트웨어 개발 프로젝트 협업을 대화형 AI로 수행할 수 있습니다.", - "tools.klavis.servers.gmail.description": "Gmail은 Google에서 제공하는 무료 이메일 서비스입니다.", - "tools.klavis.servers.gmail.readme": "Gmail의 기능을 AI 어시스턴트에 통합하세요. 이메일 읽기, 작성, 전송, 받은편지함 검색, 라벨 관리, 커뮤니케이션 정리를 자연어 대화로 수행할 수 있습니다.", - "tools.klavis.servers.google-calendar.description": "Google Calendar는 시간 관리 및 일정 예약 서비스입니다.", - "tools.klavis.servers.google-calendar.readme": "Google Calendar를 통합하여 이벤트를 확인, 생성, 관리하세요. 미팅 예약, 알림 설정, 가용 시간 확인, 자연어 명령을 통한 시간 조율이 가능합니다.", - "tools.klavis.servers.google-docs.description": "Google Docs는 Google Docs Editors 제품군에 포함된 웹 기반 워드 프로세서입니다.", - "tools.klavis.servers.google-docs.readme": "Google Docs와 통합하여 문서를 생성, 편집, 관리하세요. 콘텐츠 작성, 텍스트 서식 지정, 실시간 협업, 자연어 대화를 통한 문서 접근이 가능합니다.", - "tools.klavis.servers.google-drive.description": "Google Drive는 클라우드 스토리지 서비스입니다.", - "tools.klavis.servers.google-drive.readme": "Google Drive와 연결하여 파일을 접근, 정리, 관리하세요. 문서 검색, 파일 업로드, 콘텐츠 공유, 클라우드 저장소를 AI 지원으로 효율적으로 탐색할 수 있습니다.", - "tools.klavis.servers.google-sheets.description": "Google Sheets는 사용자가 온라인에서 스프레드시트를 생성, 편집, 협업할 수 있는 웹 기반 애플리케이션입니다.", - "tools.klavis.servers.google-sheets.readme": "Google Sheets와 연결하여 스프레드시트 데이터를 읽고, 쓰고, 분석하세요. 계산 수행, 보고서 생성, 차트 작성, AI 지원으로 표 형식 데이터를 협업 관리할 수 있습니다.", - "tools.klavis.servers.hubspot.description": "HubSpot은 인바운드 마케팅, 영업, 고객 서비스를 위한 소프트웨어 제품을 개발하는 기업입니다.", - "tools.klavis.servers.hubspot.readme": "HubSpot과 통합하여 연락처, 거래, 마케팅 캠페인을 관리하세요. CRM 데이터 접근, 파이프라인 추적, 워크플로우 자동화, 영업 및 마케팅 운영을 간소화할 수 있습니다.", - "tools.klavis.servers.jira.description": "Jira는 Atlassian에서 개발한 프로젝트 관리 및 이슈 추적 도구입니다.", - "tools.klavis.servers.jira.readme": "Jira와 통합하여 이슈를 관리하고 진행 상황을 추적하며 스프린트를 구성하세요. 티켓 생성, 상태 업데이트, 프로젝트 데이터 조회, 자연어 대화를 통한 개발 워크플로우 최적화가 가능합니다.", - "tools.klavis.servers.notion.description": "Notion은 협업 생산성과 노트 작성 애플리케이션입니다.", - "tools.klavis.servers.notion.readme": "Notion과 연결하여 워크스페이스에 접근하고 관리하세요. 페이지 생성, 콘텐츠 검색, 데이터베이스 업데이트, AI 어시스턴트와의 자연어 대화를 통해 지식 베이스를 구성할 수 있습니다.", - "tools.klavis.servers.onedrive.description": "OneDrive는 Microsoft에서 운영하는 파일 호스팅 및 동기화 서비스입니다.", - "tools.klavis.servers.onedrive.readme": "OneDrive와 연결하여 Microsoft 클라우드 파일에 접근하고 관리하세요. 파일 업로드, 다운로드, 공유, 폴더 정리, 문서 협업을 AI 기반 지원으로 수행할 수 있습니다.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail은 Microsoft의 웹메일, 연락처, 작업, 일정 서비스를 포함한 웹 기반 제품군입니다.", - "tools.klavis.servers.outlook-mail.readme": "Outlook 메일과 통합하여 Microsoft 이메일을 읽고, 전송하고, 관리하세요. 메시지 검색, 이메일 작성, 폴더 관리, 받은편지함 정리를 자연어 대화로 수행할 수 있습니다.", - "tools.klavis.servers.salesforce.description": "Salesforce는 전 세계에서 가장 널리 사용되는 고객 관계 관리(CRM) 플랫폼으로, 기업이 고객, 파트너, 잠재 고객과 연결할 수 있도록 지원합니다.", - "tools.klavis.servers.salesforce.readme": "Salesforce와 연결하여 고객 관계 및 영업 데이터를 관리하세요. 레코드 조회, 기회 업데이트, 리드 추적, 자연어 명령을 통한 CRM 워크플로우 자동화가 가능합니다.", - "tools.klavis.servers.slack.description": "Slack은 필요한 정보를 연결해주는 비즈니스용 메시징 앱입니다.", - "tools.klavis.servers.slack.readme": "Slack과 통합하여 메시지를 전송하고, 대화를 검색하며, 채널을 관리하세요. 팀과 연결하고, 커뮤니케이션 워크플로우를 자동화하며, 워크스페이스 정보를 자연어로 접근할 수 있습니다.", - "tools.klavis.servers.supabase.description": "Supabase 공식 MCP 서버", - "tools.klavis.servers.supabase.readme": "Supabase와 통합하여 데이터베이스 및 백엔드 서비스를 관리하세요. 데이터 조회, 인증 관리, 스토리지 처리, 애플리케이션 백엔드와의 상호작용을 자연어 대화로 수행할 수 있습니다.", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API 통합을 통해 텍스트 메시지, 미디어 전송 및 고객과의 대화 관리를 지원합니다. 고객 지원, 마케팅 캠페인, 자동화된 메시징 워크플로우에 적합합니다.", - "tools.klavis.servers.whatsapp.readme": "WhatsApp Business와 통합하여 메시지를 전송하고, 대화를 관리하며, 고객과 소통하세요. 메시징 워크플로우를 자동화하고, 대화형 AI를 통해 커뮤니케이션을 처리할 수 있습니다.", - "tools.klavis.servers.youtube.description": "YouTube는 사용자가 동영상을 업로드, 공유, 탐색할 수 있는 비디오 공유 플랫폼입니다. 동영상 정보, 자막, 메타데이터에 프로그래밍 방식으로 접근할 수 있습니다.", - "tools.klavis.servers.youtube.readme": "YouTube와 연결하여 동영상을 검색하고, 자막에 접근하며, 영상 정보를 가져오세요. 콘텐츠 분석, 메타데이터 추출, 자연어 대화를 통한 동영상 탐색이 가능합니다.", - "tools.klavis.servers.zendesk.description": "Zendesk는 고객 서비스 소프트웨어 회사입니다.", - "tools.klavis.servers.zendesk.readme": "Zendesk와 통합하여 지원 티켓과 고객 상호작용을 관리하세요. 지원 요청 생성, 업데이트, 추적, 고객 데이터 접근, 지원 운영을 간소화할 수 있습니다.", - "tools.klavis.tools": "개의 도구", - "tools.klavis.verifyAuth": "인증을 완료했습니다", + "tools.composio.addServer": "서버 추가", + "tools.composio.authCompleted": "인증 완료", + "tools.composio.authFailed": "인증 실패", + "tools.composio.authRequired": "인증 필요", + "tools.composio.connect": "연결", + "tools.composio.connected": "연결됨", + "tools.composio.disconnect": "연결 해제", + "tools.composio.disconnected": "연결 끊김", + "tools.composio.error": "오류", + "tools.composio.groupName": "Composio 도구", + "tools.composio.manage": "Composio 관리", + "tools.composio.manageTitle": "Composio 통합 관리", + "tools.composio.noServers": "연결된 서버 없음", + "tools.composio.notEnabled": "Composio 서비스가 활성화되지 않음", + "tools.composio.oauthRequired": "새 창에서 OAuth 인증을 완료해 주세요", + "tools.composio.pendingAuth": "인증 대기 중", + "tools.composio.serverCreated": "서버 생성 성공", + "tools.composio.serverCreatedFailed": "서버 생성 실패", + "tools.composio.serverRemoved": "서버 삭제됨", + "tools.composio.servers": "개의 서버", + "tools.composio.servers.airtable.description": "Airtable은 스프레드시트의 유연성과 데이터베이스의 강력함을 결합한 클라우드 기반 데이터베이스 및 스프레드시트 플랫폼으로, 팀이 프로젝트를 체계적으로 관리하고 협업할 수 있도록 지원합니다.", + "tools.composio.servers.airtable.readme": "Airtable과 통합하여 데이터베이스와 워크플로우를 관리하세요. 레코드 조회, 항목 생성, 데이터 업데이트, 사용자 정의 뷰와 강력한 추적 기능으로 작업을 자동화할 수 있습니다.", + "tools.composio.servers.cal-com.description": "Cal.com은 이메일을 주고받지 않고도 회의를 예약할 수 있도록 도와주는 오픈소스 일정 관리 플랫폼입니다. 이벤트 유형, 예약, 가용성 관리 및 캘린더 통합이 가능합니다.", + "tools.composio.servers.cal-com.readme": "Cal.com과 연결하여 일정과 약속을 관리하세요. 가용 시간 확인, 미팅 예약, 이벤트 유형 관리, 자연어 대화를 통한 캘린더 자동화가 가능합니다.", + "tools.composio.servers.clickup.description": "ClickUp은 프로젝트 관리와 생산성을 위한 종합 플랫폼으로, 팀이 작업을 체계적으로 정리하고 협업할 수 있도록 지원합니다.", + "tools.composio.servers.clickup.readme": "ClickUp과 연결하여 작업을 관리하고 프로젝트를 추적하며 업무를 체계화하세요. 작업 생성, 상태 업데이트, 맞춤형 워크플로우 관리, 팀과의 협업이 자연어 명령으로 가능합니다.", + "tools.composio.servers.confluence.description": "Confluence는 지식과 협업이 만나는 팀 워크스페이스입니다.", + "tools.composio.servers.confluence.readme": "Confluence와 연결하여 팀 문서를 접근하고 관리하세요. 페이지 검색, 콘텐츠 생성, 공간 구성, 대화형 AI 지원으로 지식 베이스를 구축할 수 있습니다.", + "tools.composio.servers.dropbox.description": "Dropbox 클라우드 스토리지를 위한 완전한 파일 관리 솔루션입니다. 파일 및 폴더 업로드, 다운로드, 정리, 공유 및 협업 관리, 버전 관리, 파일 요청 생성, 일괄 작업 수행이 가능합니다.", + "tools.composio.servers.dropbox.readme": "Dropbox와 통합하여 파일에 접근하고 관리하세요. 파일 업로드, 다운로드, 공유, 폴더 관리, 버전 제어, 클라우드 저장소 정리를 대화형 AI로 수행할 수 있습니다.", + "tools.composio.servers.figma.description": "Figma는 웹 및 모바일 애플리케이션을 위한 협업 인터페이스 디자인 도구입니다.", + "tools.composio.servers.figma.readme": "Figma와 연결하여 디자인 파일에 접근하고 프로젝트에 협업하세요. 디자인 보기, 에셋 내보내기, 구성 요소 탐색, 자연어 대화를 통한 디자인 워크플로우 관리가 가능합니다.", + "tools.composio.servers.github.description": "향상된 GitHub MCP 서버", + "tools.composio.servers.github.readme": "GitHub와 연결하여 저장소, 이슈, 풀 리퀘스트, 코드를 관리하세요. 코드 검색, 변경 사항 검토, 브랜치 생성, 소프트웨어 개발 프로젝트 협업을 대화형 AI로 수행할 수 있습니다.", + "tools.composio.servers.gmail.description": "Gmail은 Google에서 제공하는 무료 이메일 서비스입니다.", + "tools.composio.servers.gmail.readme": "Gmail의 기능을 AI 어시스턴트에 통합하세요. 이메일 읽기, 작성, 전송, 받은편지함 검색, 라벨 관리, 커뮤니케이션 정리를 자연어 대화로 수행할 수 있습니다.", + "tools.composio.servers.google-calendar.description": "Google Calendar는 시간 관리 및 일정 예약 서비스입니다.", + "tools.composio.servers.google-calendar.readme": "Google Calendar를 통합하여 이벤트를 확인, 생성, 관리하세요. 미팅 예약, 알림 설정, 가용 시간 확인, 자연어 명령을 통한 시간 조율이 가능합니다.", + "tools.composio.servers.google-docs.description": "Google Docs는 Google Docs Editors 제품군에 포함된 웹 기반 워드 프로세서입니다.", + "tools.composio.servers.google-docs.readme": "Google Docs와 통합하여 문서를 생성, 편집, 관리하세요. 콘텐츠 작성, 텍스트 서식 지정, 실시간 협업, 자연어 대화를 통한 문서 접근이 가능합니다.", + "tools.composio.servers.google-drive.description": "Google Drive는 클라우드 스토리지 서비스입니다.", + "tools.composio.servers.google-drive.readme": "Google Drive와 연결하여 파일을 접근, 정리, 관리하세요. 문서 검색, 파일 업로드, 콘텐츠 공유, 클라우드 저장소를 AI 지원으로 효율적으로 탐색할 수 있습니다.", + "tools.composio.servers.google-sheets.description": "Google Sheets는 사용자가 온라인에서 스프레드시트를 생성, 편집, 협업할 수 있는 웹 기반 애플리케이션입니다.", + "tools.composio.servers.google-sheets.readme": "Google Sheets와 연결하여 스프레드시트 데이터를 읽고, 쓰고, 분석하세요. 계산 수행, 보고서 생성, 차트 작성, AI 지원으로 표 형식 데이터를 협업 관리할 수 있습니다.", + "tools.composio.servers.hubspot.description": "HubSpot은 인바운드 마케팅, 영업, 고객 서비스를 위한 소프트웨어 제품을 개발하는 기업입니다.", + "tools.composio.servers.hubspot.readme": "HubSpot과 통합하여 연락처, 거래, 마케팅 캠페인을 관리하세요. CRM 데이터 접근, 파이프라인 추적, 워크플로우 자동화, 영업 및 마케팅 운영을 간소화할 수 있습니다.", + "tools.composio.servers.jira.description": "Jira는 Atlassian에서 개발한 프로젝트 관리 및 이슈 추적 도구입니다.", + "tools.composio.servers.jira.readme": "Jira와 통합하여 이슈를 관리하고 진행 상황을 추적하며 스프린트를 구성하세요. 티켓 생성, 상태 업데이트, 프로젝트 데이터 조회, 자연어 대화를 통한 개발 워크플로우 최적화가 가능합니다.", + "tools.composio.servers.notion.description": "Notion은 협업 생산성과 노트 작성 애플리케이션입니다.", + "tools.composio.servers.notion.readme": "Notion과 연결하여 워크스페이스에 접근하고 관리하세요. 페이지 생성, 콘텐츠 검색, 데이터베이스 업데이트, AI 어시스턴트와의 자연어 대화를 통해 지식 베이스를 구성할 수 있습니다.", + "tools.composio.servers.onedrive.description": "OneDrive는 Microsoft에서 운영하는 파일 호스팅 및 동기화 서비스입니다.", + "tools.composio.servers.onedrive.readme": "OneDrive와 연결하여 Microsoft 클라우드 파일에 접근하고 관리하세요. 파일 업로드, 다운로드, 공유, 폴더 정리, 문서 협업을 AI 기반 지원으로 수행할 수 있습니다.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail은 Microsoft의 웹메일, 연락처, 작업, 일정 서비스를 포함한 웹 기반 제품군입니다.", + "tools.composio.servers.outlook-mail.readme": "Outlook 메일과 통합하여 Microsoft 이메일을 읽고, 전송하고, 관리하세요. 메시지 검색, 이메일 작성, 폴더 관리, 받은편지함 정리를 자연어 대화로 수행할 수 있습니다.", + "tools.composio.servers.salesforce.description": "Salesforce는 전 세계에서 가장 널리 사용되는 고객 관계 관리(CRM) 플랫폼으로, 기업이 고객, 파트너, 잠재 고객과 연결할 수 있도록 지원합니다.", + "tools.composio.servers.salesforce.readme": "Salesforce와 연결하여 고객 관계 및 영업 데이터를 관리하세요. 레코드 조회, 기회 업데이트, 리드 추적, 자연어 명령을 통한 CRM 워크플로우 자동화가 가능합니다.", + "tools.composio.servers.slack.description": "Slack은 필요한 정보를 연결해주는 비즈니스용 메시징 앱입니다.", + "tools.composio.servers.slack.readme": "Slack과 통합하여 메시지를 전송하고, 대화를 검색하며, 채널을 관리하세요. 팀과 연결하고, 커뮤니케이션 워크플로우를 자동화하며, 워크스페이스 정보를 자연어로 접근할 수 있습니다.", + "tools.composio.servers.supabase.description": "Supabase 공식 MCP 서버", + "tools.composio.servers.supabase.readme": "Supabase와 통합하여 데이터베이스 및 백엔드 서비스를 관리하세요. 데이터 조회, 인증 관리, 스토리지 처리, 애플리케이션 백엔드와의 상호작용을 자연어 대화로 수행할 수 있습니다.", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API 통합을 통해 텍스트 메시지, 미디어 전송 및 고객과의 대화 관리를 지원합니다. 고객 지원, 마케팅 캠페인, 자동화된 메시징 워크플로우에 적합합니다.", + "tools.composio.servers.whatsapp.readme": "WhatsApp Business와 통합하여 메시지를 전송하고, 대화를 관리하며, 고객과 소통하세요. 메시징 워크플로우를 자동화하고, 대화형 AI를 통해 커뮤니케이션을 처리할 수 있습니다.", + "tools.composio.servers.youtube.description": "YouTube는 사용자가 동영상을 업로드, 공유, 탐색할 수 있는 비디오 공유 플랫폼입니다. 동영상 정보, 자막, 메타데이터에 프로그래밍 방식으로 접근할 수 있습니다.", + "tools.composio.servers.youtube.readme": "YouTube와 연결하여 동영상을 검색하고, 자막에 접근하며, 영상 정보를 가져오세요. 콘텐츠 분석, 메타데이터 추출, 자연어 대화를 통한 동영상 탐색이 가능합니다.", + "tools.composio.servers.zendesk.description": "Zendesk는 고객 서비스 소프트웨어 회사입니다.", + "tools.composio.servers.zendesk.readme": "Zendesk와 통합하여 지원 티켓과 고객 상호작용을 관리하세요. 지원 요청 생성, 업데이트, 추적, 고객 데이터 접근, 지원 운영을 간소화할 수 있습니다.", + "tools.composio.tools": "개의 도구", + "tools.composio.verifyAuth": "인증을 완료했습니다", "tools.lobehubSkill.authorize": "권한 부여", "tools.lobehubSkill.connect": "연결", "tools.lobehubSkill.connected": "연결됨", diff --git a/locales/nl-NL/setting.json b/locales/nl-NL/setting.json index 090f274b6ae..42f233ee625 100644 --- a/locales/nl-NL/setting.json +++ b/locales/nl-NL/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "{{name}} verwijderen", "tools.builtins.uninstalled": "Verwijderd", "tools.disabled": "Het huidige model ondersteunt geen functieaanroepen en kan de vaardigheid niet gebruiken", - "tools.klavis.addServer": "Server Toevoegen", - "tools.klavis.authCompleted": "Authenticatie Voltooid", - "tools.klavis.authFailed": "Authenticatie Mislukt", - "tools.klavis.authRequired": "Authenticatie Vereist", - "tools.klavis.connect": "Verbinden", - "tools.klavis.connected": "Verbonden", - "tools.klavis.disconnect": "Verbinding verbreken", - "tools.klavis.disconnected": "Verbinding verbroken", - "tools.klavis.error": "Fout", - "tools.klavis.groupName": "Klavis Tools", - "tools.klavis.manage": "Beheer Klavis", - "tools.klavis.manageTitle": "Beheer Klavis-integratie", - "tools.klavis.noServers": "Geen verbonden servers", - "tools.klavis.notEnabled": "Klavis-service niet ingeschakeld", - "tools.klavis.oauthRequired": "Voltooi OAuth-authenticatie in het nieuwe venster", - "tools.klavis.pendingAuth": "Authenticatie In Afwachting", - "tools.klavis.remove": "Verwijderen", - "tools.klavis.removeConfirm.desc": "{{name}} wordt permanent verwijderd uit je verbonden diensten. Deze actie kan niet ongedaan worden gemaakt.", - "tools.klavis.removeConfirm.title": "{{name}} verwijderen?", - "tools.klavis.serverCreated": "Server succesvol aangemaakt", - "tools.klavis.serverCreatedFailed": "Server aanmaken mislukt", - "tools.klavis.serverRemoved": "Server verwijderd", - "tools.klavis.servers": "servers", - "tools.klavis.servers.airtable.description": "Airtable is een cloudgebaseerd database- en spreadsheetplatform dat de flexibiliteit van een spreadsheet combineert met de kracht van een database, waardoor teams projecten kunnen organiseren, volgen en samenwerken met aanpasbare weergaven en krachtige automatiseringsfuncties.", - "tools.klavis.servers.airtable.readme": "Integreer met Airtable om je databases en workflows te beheren. Doorzoek records, maak nieuwe items aan, werk gegevens bij en automatiseer processen met aanpasbare weergaven en krachtige trackingfuncties.", - "tools.klavis.servers.cal-com.description": "Cal.com is een open-source planningsplatform dat helpt bij het plannen van afspraken zonder eindeloos heen-en-weer gemail.", - "tools.klavis.servers.cal-com.readme": "Verbind met Cal.com om je planning en afspraken te beheren. Bekijk beschikbaarheid, plan vergaderingen, beheer evenementtypes en automatiseer je agenda via natuurlijke gesprekken.", - "tools.klavis.servers.clickup.description": "ClickUp is een uitgebreid platform voor projectbeheer en productiviteit dat teams helpt taken te organiseren, projecten te beheren en effectief samen te werken met aanpasbare workflows en krachtige trackingfuncties.", - "tools.klavis.servers.clickup.readme": "Verbind met ClickUp om taken te beheren, projecten te volgen en je werk te organiseren. Maak taken aan, werk statussen bij, beheer aangepaste workflows en werk samen met je team via natuurlijke taalopdrachten.", - "tools.klavis.servers.confluence.description": "Confluence is een teamwerkruimte waar kennis en samenwerking samenkomen.", - "tools.klavis.servers.confluence.readme": "Verbind met Confluence om teamdocumentatie te openen en te beheren. Doorzoek pagina’s, maak content aan, organiseer ruimtes en bouw je kennisbank met hulp van conversatie-AI.", - "tools.klavis.servers.dropbox.description": "Volledige bestandsbeheersoplossing voor Dropbox-cloudopslag. Uploaden, downloaden, bestanden en mappen organiseren, delen beheren, versies beheren, bestandsverzoeken aanmaken en batchbewerkingen uitvoeren op je Dropbox-bestanden en -mappen.", - "tools.klavis.servers.dropbox.readme": "Integreer met Dropbox om toegang te krijgen tot en beheer te voeren over je bestanden. Upload, download en deel bestanden, beheer mappen, versies en organiseer je cloudopslag via conversatie-AI.", - "tools.klavis.servers.figma.description": "Figma is een collaboratieve tool voor interfaceontwerp voor web- en mobiele applicaties.", - "tools.klavis.servers.figma.readme": "Verbind met Figma om ontwerpbestanden te openen en samen te werken aan projecten. Bekijk ontwerpen, exporteer assets, blader door componenten en beheer je designworkflow via natuurlijke gesprekken.", - "tools.klavis.servers.github.description": "Verbeterde GitHub MCP-server", - "tools.klavis.servers.github.readme": "Verbind met GitHub om repositories, issues, pull requests en code te beheren. Doorzoek code, beoordeel wijzigingen, maak branches aan en werk samen aan softwareprojecten via conversatie-AI.", - "tools.klavis.servers.gmail.description": "Gmail is een gratis e-maildienst van Google.", - "tools.klavis.servers.gmail.readme": "Haal de kracht van Gmail direct naar je AI-assistent. Lees, schrijf en verstuur e-mails, doorzoek je inbox, beheer labels en organiseer je communicatie—allemaal via natuurlijke gesprekken.", - "tools.klavis.servers.google-calendar.description": "Google Agenda is een dienst voor tijdbeheer en planning.", - "tools.klavis.servers.google-calendar.readme": "Integreer Google Agenda om je evenementen te bekijken, aan te maken en te beheren. Plan vergaderingen, stel herinneringen in, controleer beschikbaarheid en coördineer je tijd via natuurlijke taalopdrachten.", - "tools.klavis.servers.google-docs.description": "Google Documenten is een tekstverwerker die deel uitmaakt van de gratis, webgebaseerde Google Docs Editors-suite.", - "tools.klavis.servers.google-docs.readme": "Integreer met Google Documenten om documenten aan te maken, te bewerken en te beheren. Schrijf content, formatteer tekst, werk realtime samen en open je documenten via natuurlijke gesprekken.", - "tools.klavis.servers.google-drive.description": "Google Drive is een cloudopslagdienst.", - "tools.klavis.servers.google-drive.readme": "Verbind met Google Drive om toegang te krijgen tot, te organiseren en beheer te voeren over je bestanden. Doorzoek documenten, upload bestanden, deel content en navigeer efficiënt door je cloudopslag met AI-hulp.", - "tools.klavis.servers.google-sheets.description": "Google Spreadsheets is een webgebaseerde spreadsheetapplicatie waarmee gebruikers online spreadsheets kunnen maken, bewerken en samenwerken.", - "tools.klavis.servers.google-sheets.readme": "Verbind met Google Spreadsheets om spreadsheetgegevens te lezen, schrijven en analyseren. Voer berekeningen uit, genereer rapporten, maak grafieken en beheer tabulaire data samen met AI-hulp.", - "tools.klavis.servers.hubspot.description": "HubSpot ontwikkelt softwareproducten voor inbound marketing, verkoop en klantenservice.", - "tools.klavis.servers.hubspot.readme": "Integreer met HubSpot om contacten, deals en marketingcampagnes te beheren. Toegang tot CRM-gegevens, volg pijplijnen, automatiseer workflows en stroomlijn je verkoop- en marketingprocessen.", - "tools.klavis.servers.jira.description": "Jira is een tool voor projectbeheer en issue-tracking, ontwikkeld door Atlassian.", - "tools.klavis.servers.jira.readme": "Integreer met Jira om issues te beheren, voortgang te volgen en sprints te organiseren. Maak tickets aan, werk statussen bij, doorzoek projectgegevens en stroomlijn je ontwikkelworkflow via natuurlijke gesprekken.", - "tools.klavis.servers.notion.description": "Notion is een collaboratieve productiviteits- en notitieapplicatie.", - "tools.klavis.servers.notion.readme": "Verbind met Notion om toegang te krijgen tot en beheer te voeren over je werkruimte. Maak pagina’s aan, doorzoek inhoud, werk databases bij en organiseer je kennisbank—allemaal via natuurlijke gesprekken met je AI-assistent.", - "tools.klavis.servers.onedrive.description": "OneDrive is een bestandsopslag- en synchronisatiedienst van Microsoft.", - "tools.klavis.servers.onedrive.readme": "Verbind met OneDrive om toegang te krijgen tot en beheer te voeren over je Microsoft-cloudbestanden. Upload, download en deel bestanden, organiseer mappen en werk samen aan documenten met AI-ondersteuning.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail is een webgebaseerde suite van e-mail, contacten, taken en agenda van Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Integreer met Outlook Mail om je Microsoft-e-mails te lezen, verzenden en beheren. Doorzoek berichten, stel e-mails op, beheer mappen en organiseer je inbox via natuurlijke gesprekken.", - "tools.klavis.servers.salesforce.description": "Salesforce is ’s werelds toonaangevende CRM-platform dat bedrijven helpt contact te maken met klanten, partners en prospects.", - "tools.klavis.servers.salesforce.readme": "Verbind met Salesforce om klantrelaties en verkoopgegevens te beheren. Doorzoek records, werk kansen bij, volg leads en automatiseer je CRM-workflows via natuurlijke taalopdrachten.", - "tools.klavis.servers.slack.description": "Slack is een zakelijke berichtenapp die mensen verbindt met de informatie die ze nodig hebben.", - "tools.klavis.servers.slack.readme": "Integreer met Slack om berichten te verzenden, gesprekken te doorzoeken en kanalen te beheren. Verbind met je team, automatiseer communicatieprocessen en krijg toegang tot werkruimte-informatie via natuurlijke taal.", - "tools.klavis.servers.supabase.description": "Officiële Supabase MCP-server", - "tools.klavis.servers.supabase.readme": "Integreer met Supabase om je database en backendservices te beheren. Doorzoek gegevens, beheer authenticatie, verwerk opslag en communiceer met je applicatiebackend via natuurlijke gesprekken.", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API-integratie waarmee je tekstberichten, media kunt verzenden en gesprekken met klanten kunt beheren. Ideaal voor klantenservice, marketingcampagnes en geautomatiseerde berichtenstromen via het officiële WhatsApp Business-platform.", - "tools.klavis.servers.whatsapp.readme": "Integreer met WhatsApp Business om berichten te verzenden, gesprekken te beheren en klanten te betrekken. Automatiseer berichtprocessen en beheer communicatie via conversatie-AI.", - "tools.klavis.servers.youtube.description": "YouTube is een videoplatform waar gebruikers content kunnen uploaden, delen en ontdekken. Toegang tot videogegevens, transcripties en metadata via programmatische middelen.", - "tools.klavis.servers.youtube.readme": "Verbind met YouTube om video’s te zoeken, transcripties te bekijken en videogegevens op te halen. Analyseer content, extraheer metadata en ontdek video’s via natuurlijke gesprekken.", - "tools.klavis.servers.zendesk.description": "Zendesk is een softwarebedrijf voor klantenservice.", - "tools.klavis.servers.zendesk.readme": "Integreer met Zendesk om supporttickets en klantinteracties te beheren. Maak supportverzoeken aan, werk ze bij, volg ze op, krijg toegang tot klantgegevens en stroomlijn je supportprocessen.", - "tools.klavis.tools": "tools", - "tools.klavis.verifyAuth": "Ik heb de authenticatie voltooid", + "tools.composio.addServer": "Server Toevoegen", + "tools.composio.authCompleted": "Authenticatie Voltooid", + "tools.composio.authFailed": "Authenticatie Mislukt", + "tools.composio.authRequired": "Authenticatie Vereist", + "tools.composio.connect": "Verbinden", + "tools.composio.connected": "Verbonden", + "tools.composio.disconnect": "Verbinding verbreken", + "tools.composio.disconnected": "Verbinding verbroken", + "tools.composio.error": "Fout", + "tools.composio.groupName": "Composio Tools", + "tools.composio.manage": "Beheer Composio", + "tools.composio.manageTitle": "Beheer Composio-integratie", + "tools.composio.noServers": "Geen verbonden servers", + "tools.composio.notEnabled": "Composio-service niet ingeschakeld", + "tools.composio.oauthRequired": "Voltooi OAuth-authenticatie in het nieuwe venster", + "tools.composio.pendingAuth": "Authenticatie In Afwachting", + "tools.composio.serverCreated": "Server succesvol aangemaakt", + "tools.composio.serverCreatedFailed": "Server aanmaken mislukt", + "tools.composio.serverRemoved": "Server verwijderd", + "tools.composio.servers": "servers", + "tools.composio.servers.airtable.description": "Airtable is een cloudgebaseerd database- en spreadsheetplatform dat de flexibiliteit van een spreadsheet combineert met de kracht van een database, waardoor teams projecten kunnen organiseren, volgen en samenwerken met aanpasbare weergaven en krachtige automatiseringsfuncties.", + "tools.composio.servers.airtable.readme": "Integreer met Airtable om je databases en workflows te beheren. Doorzoek records, maak nieuwe items aan, werk gegevens bij en automatiseer processen met aanpasbare weergaven en krachtige trackingfuncties.", + "tools.composio.servers.cal-com.description": "Cal.com is een open-source planningsplatform dat helpt bij het plannen van afspraken zonder eindeloos heen-en-weer gemail.", + "tools.composio.servers.cal-com.readme": "Verbind met Cal.com om je planning en afspraken te beheren. Bekijk beschikbaarheid, plan vergaderingen, beheer evenementtypes en automatiseer je agenda via natuurlijke gesprekken.", + "tools.composio.servers.clickup.description": "ClickUp is een uitgebreid platform voor projectbeheer en productiviteit dat teams helpt taken te organiseren, projecten te beheren en effectief samen te werken met aanpasbare workflows en krachtige trackingfuncties.", + "tools.composio.servers.clickup.readme": "Verbind met ClickUp om taken te beheren, projecten te volgen en je werk te organiseren. Maak taken aan, werk statussen bij, beheer aangepaste workflows en werk samen met je team via natuurlijke taalopdrachten.", + "tools.composio.servers.confluence.description": "Confluence is een teamwerkruimte waar kennis en samenwerking samenkomen.", + "tools.composio.servers.confluence.readme": "Verbind met Confluence om teamdocumentatie te openen en te beheren. Doorzoek pagina’s, maak content aan, organiseer ruimtes en bouw je kennisbank met hulp van conversatie-AI.", + "tools.composio.servers.dropbox.description": "Volledige bestandsbeheersoplossing voor Dropbox-cloudopslag. Uploaden, downloaden, bestanden en mappen organiseren, delen beheren, versies beheren, bestandsverzoeken aanmaken en batchbewerkingen uitvoeren op je Dropbox-bestanden en -mappen.", + "tools.composio.servers.dropbox.readme": "Integreer met Dropbox om toegang te krijgen tot en beheer te voeren over je bestanden. Upload, download en deel bestanden, beheer mappen, versies en organiseer je cloudopslag via conversatie-AI.", + "tools.composio.servers.figma.description": "Figma is een collaboratieve tool voor interfaceontwerp voor web- en mobiele applicaties.", + "tools.composio.servers.figma.readme": "Verbind met Figma om ontwerpbestanden te openen en samen te werken aan projecten. Bekijk ontwerpen, exporteer assets, blader door componenten en beheer je designworkflow via natuurlijke gesprekken.", + "tools.composio.servers.github.description": "Verbeterde GitHub MCP-server", + "tools.composio.servers.github.readme": "Verbind met GitHub om repositories, issues, pull requests en code te beheren. Doorzoek code, beoordeel wijzigingen, maak branches aan en werk samen aan softwareprojecten via conversatie-AI.", + "tools.composio.servers.gmail.description": "Gmail is een gratis e-maildienst van Google.", + "tools.composio.servers.gmail.readme": "Haal de kracht van Gmail direct naar je AI-assistent. Lees, schrijf en verstuur e-mails, doorzoek je inbox, beheer labels en organiseer je communicatie—allemaal via natuurlijke gesprekken.", + "tools.composio.servers.google-calendar.description": "Google Agenda is een dienst voor tijdbeheer en planning.", + "tools.composio.servers.google-calendar.readme": "Integreer Google Agenda om je evenementen te bekijken, aan te maken en te beheren. Plan vergaderingen, stel herinneringen in, controleer beschikbaarheid en coördineer je tijd via natuurlijke taalopdrachten.", + "tools.composio.servers.google-docs.description": "Google Documenten is een tekstverwerker die deel uitmaakt van de gratis, webgebaseerde Google Docs Editors-suite.", + "tools.composio.servers.google-docs.readme": "Integreer met Google Documenten om documenten aan te maken, te bewerken en te beheren. Schrijf content, formatteer tekst, werk realtime samen en open je documenten via natuurlijke gesprekken.", + "tools.composio.servers.google-drive.description": "Google Drive is een cloudopslagdienst.", + "tools.composio.servers.google-drive.readme": "Verbind met Google Drive om toegang te krijgen tot, te organiseren en beheer te voeren over je bestanden. Doorzoek documenten, upload bestanden, deel content en navigeer efficiënt door je cloudopslag met AI-hulp.", + "tools.composio.servers.google-sheets.description": "Google Spreadsheets is een webgebaseerde spreadsheetapplicatie waarmee gebruikers online spreadsheets kunnen maken, bewerken en samenwerken.", + "tools.composio.servers.google-sheets.readme": "Verbind met Google Spreadsheets om spreadsheetgegevens te lezen, schrijven en analyseren. Voer berekeningen uit, genereer rapporten, maak grafieken en beheer tabulaire data samen met AI-hulp.", + "tools.composio.servers.hubspot.description": "HubSpot ontwikkelt softwareproducten voor inbound marketing, verkoop en klantenservice.", + "tools.composio.servers.hubspot.readme": "Integreer met HubSpot om contacten, deals en marketingcampagnes te beheren. Toegang tot CRM-gegevens, volg pijplijnen, automatiseer workflows en stroomlijn je verkoop- en marketingprocessen.", + "tools.composio.servers.jira.description": "Jira is een tool voor projectbeheer en issue-tracking, ontwikkeld door Atlassian.", + "tools.composio.servers.jira.readme": "Integreer met Jira om issues te beheren, voortgang te volgen en sprints te organiseren. Maak tickets aan, werk statussen bij, doorzoek projectgegevens en stroomlijn je ontwikkelworkflow via natuurlijke gesprekken.", + "tools.composio.servers.notion.description": "Notion is een collaboratieve productiviteits- en notitieapplicatie.", + "tools.composio.servers.notion.readme": "Verbind met Notion om toegang te krijgen tot en beheer te voeren over je werkruimte. Maak pagina’s aan, doorzoek inhoud, werk databases bij en organiseer je kennisbank—allemaal via natuurlijke gesprekken met je AI-assistent.", + "tools.composio.servers.onedrive.description": "OneDrive is een bestandsopslag- en synchronisatiedienst van Microsoft.", + "tools.composio.servers.onedrive.readme": "Verbind met OneDrive om toegang te krijgen tot en beheer te voeren over je Microsoft-cloudbestanden. Upload, download en deel bestanden, organiseer mappen en werk samen aan documenten met AI-ondersteuning.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail is een webgebaseerde suite van e-mail, contacten, taken en agenda van Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Integreer met Outlook Mail om je Microsoft-e-mails te lezen, verzenden en beheren. Doorzoek berichten, stel e-mails op, beheer mappen en organiseer je inbox via natuurlijke gesprekken.", + "tools.composio.servers.salesforce.description": "Salesforce is ’s werelds toonaangevende CRM-platform dat bedrijven helpt contact te maken met klanten, partners en prospects.", + "tools.composio.servers.salesforce.readme": "Verbind met Salesforce om klantrelaties en verkoopgegevens te beheren. Doorzoek records, werk kansen bij, volg leads en automatiseer je CRM-workflows via natuurlijke taalopdrachten.", + "tools.composio.servers.slack.description": "Slack is een zakelijke berichtenapp die mensen verbindt met de informatie die ze nodig hebben.", + "tools.composio.servers.slack.readme": "Integreer met Slack om berichten te verzenden, gesprekken te doorzoeken en kanalen te beheren. Verbind met je team, automatiseer communicatieprocessen en krijg toegang tot werkruimte-informatie via natuurlijke taal.", + "tools.composio.servers.supabase.description": "Officiële Supabase MCP-server", + "tools.composio.servers.supabase.readme": "Integreer met Supabase om je database en backendservices te beheren. Doorzoek gegevens, beheer authenticatie, verwerk opslag en communiceer met je applicatiebackend via natuurlijke gesprekken.", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API-integratie waarmee je tekstberichten, media kunt verzenden en gesprekken met klanten kunt beheren. Ideaal voor klantenservice, marketingcampagnes en geautomatiseerde berichtenstromen via het officiële WhatsApp Business-platform.", + "tools.composio.servers.whatsapp.readme": "Integreer met WhatsApp Business om berichten te verzenden, gesprekken te beheren en klanten te betrekken. Automatiseer berichtprocessen en beheer communicatie via conversatie-AI.", + "tools.composio.servers.youtube.description": "YouTube is een videoplatform waar gebruikers content kunnen uploaden, delen en ontdekken. Toegang tot videogegevens, transcripties en metadata via programmatische middelen.", + "tools.composio.servers.youtube.readme": "Verbind met YouTube om video’s te zoeken, transcripties te bekijken en videogegevens op te halen. Analyseer content, extraheer metadata en ontdek video’s via natuurlijke gesprekken.", + "tools.composio.servers.zendesk.description": "Zendesk is een softwarebedrijf voor klantenservice.", + "tools.composio.servers.zendesk.readme": "Integreer met Zendesk om supporttickets en klantinteracties te beheren. Maak supportverzoeken aan, werk ze bij, volg ze op, krijg toegang tot klantgegevens en stroomlijn je supportprocessen.", + "tools.composio.tools": "tools", + "tools.composio.verifyAuth": "Ik heb de authenticatie voltooid", "tools.lobehubSkill.authorize": "Autoriseren", "tools.lobehubSkill.connect": "Verbinden", "tools.lobehubSkill.connected": "Verbonden", diff --git a/locales/pl-PL/setting.json b/locales/pl-PL/setting.json index 862e43e01e3..1532f14b73d 100644 --- a/locales/pl-PL/setting.json +++ b/locales/pl-PL/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Odinstaluj {{name}}", "tools.builtins.uninstalled": "Odinstalowano", "tools.disabled": "Bieżący model nie obsługuje wywołań funkcji i nie może korzystać z tej umiejętności", - "tools.klavis.addServer": "Dodaj serwer", - "tools.klavis.authCompleted": "Uwierzytelnienie zakończone", - "tools.klavis.authFailed": "Uwierzytelnienie nie powiodło się", - "tools.klavis.authRequired": "Wymagane uwierzytelnienie", - "tools.klavis.connect": "Połącz", - "tools.klavis.connected": "Połączono", - "tools.klavis.disconnect": "Odłącz", - "tools.klavis.disconnected": "Rozłączono", - "tools.klavis.error": "Błąd", - "tools.klavis.groupName": "Narzędzia Klavis", - "tools.klavis.manage": "Zarządzaj Klavis", - "tools.klavis.manageTitle": "Zarządzanie integracją Klavis", - "tools.klavis.noServers": "Brak połączonych serwerów", - "tools.klavis.notEnabled": "Usługa Klavis nie jest włączona", - "tools.klavis.oauthRequired": "Proszę zakończyć uwierzytelnienie OAuth w nowym oknie", - "tools.klavis.pendingAuth": "Oczekujące uwierzytelnienie", - "tools.klavis.remove": "Usuń", - "tools.klavis.removeConfirm.desc": "{{name}} zostanie trwale usunięty z Twoich połączonych usług. Tej operacji nie można cofnąć.", - "tools.klavis.removeConfirm.title": "Usunąć {{name}}?", - "tools.klavis.serverCreated": "Serwer utworzony pomyślnie", - "tools.klavis.serverCreatedFailed": "Nie udało się utworzyć serwera", - "tools.klavis.serverRemoved": "Serwer usunięty", - "tools.klavis.servers": "serwery", - "tools.klavis.servers.airtable.description": "Airtable to platforma baz danych i arkuszy kalkulacyjnych w chmurze, łącząca elastyczność arkusza z mocą bazy danych, umożliwiająca zespołom organizowanie, śledzenie i współpracę nad projektami dzięki konfigurowalnym widokom i zaawansowanej automatyzacji.", - "tools.klavis.servers.airtable.readme": "Zintegruj się z Airtable, aby zarządzać bazami danych i przepływami pracy. Wyszukuj rekordy, twórz wpisy, aktualizuj dane i automatyzuj operacje dzięki konfigurowalnym widokom i zaawansowanym funkcjom śledzenia.", - "tools.klavis.servers.cal-com.description": "Cal.com to otwartoźródłowa platforma do planowania spotkań, która eliminuje konieczność wymiany wielu e-maili. Zarządzaj typami wydarzeń, rezerwacjami, dostępnością i integruj się z kalendarzami, aby płynnie planować spotkania.", - "tools.klavis.servers.cal-com.readme": "Połącz się z Cal.com, aby zarządzać harmonogramem i spotkaniami. Przeglądaj dostępność, rezerwuj spotkania, zarządzaj typami wydarzeń i automatyzuj kalendarz za pomocą naturalnej rozmowy.", - "tools.klavis.servers.clickup.description": "ClickUp to kompleksowa platforma do zarządzania projektami i produktywnością, która pomaga zespołom organizować zadania, zarządzać projektami i skutecznie współpracować dzięki konfigurowalnym przepływom pracy i zaawansowanym funkcjom śledzenia.", - "tools.klavis.servers.clickup.readme": "Połącz się z ClickUp, aby zarządzać zadaniami, śledzić projekty i organizować pracę. Twórz zadania, aktualizuj statusy, zarządzaj niestandardowymi przepływami pracy i współpracuj z zespołem za pomocą poleceń w języku naturalnym.", - "tools.klavis.servers.confluence.description": "Confluence to przestrzeń robocza zespołu, w której wiedza i współpraca się spotykają.", - "tools.klavis.servers.confluence.readme": "Połącz się z Confluence, aby uzyskać dostęp do dokumentacji zespołu i nią zarządzać. Wyszukuj strony, twórz treści, organizuj przestrzenie i buduj bazę wiedzy z pomocą konwersacyjnej AI.", - "tools.klavis.servers.dropbox.description": "Kompleksowe zarządzanie plikami w chmurze Dropbox. Przesyłaj, pobieraj, organizuj pliki i foldery, zarządzaj udostępnianiem i współpracą, obsługuj wersje plików, twórz żądania plików i wykonuj operacje zbiorcze.", - "tools.klavis.servers.dropbox.readme": "Zintegruj się z Dropbox, aby uzyskać dostęp do plików i nimi zarządzać. Przesyłaj, pobieraj, udostępniaj pliki, zarządzaj folderami, obsługuj wersje plików i organizuj przestrzeń w chmurze za pomocą AI.", - "tools.klavis.servers.figma.description": "Figma to narzędzie do projektowania interfejsów dla aplikacji internetowych i mobilnych, umożliwiające współpracę.", - "tools.klavis.servers.figma.readme": "Połącz się z Figma, aby uzyskać dostęp do plików projektowych i współpracować nad projektami. Przeglądaj projekty, eksportuj zasoby, przeglądaj komponenty i zarządzaj procesem projektowym za pomocą naturalnej rozmowy.", - "tools.klavis.servers.github.description": "Ulepszony serwer MCP GitHub", - "tools.klavis.servers.github.readme": "Połącz się z GitHub, aby zarządzać repozytoriami, zgłoszeniami, pull requestami i kodem. Wyszukuj kod, przeglądaj zmiany, twórz gałęzie i współpracuj nad projektami programistycznymi z pomocą konwersacyjnej AI.", - "tools.klavis.servers.gmail.description": "Gmail to bezpłatna usługa e-mail od Google", - "tools.klavis.servers.gmail.readme": "Wykorzystaj możliwości Gmaila bezpośrednio w swoim asystencie AI. Czytaj, twórz i wysyłaj e-maile, przeszukuj skrzynkę odbiorczą, zarządzaj etykietami i organizuj komunikację — wszystko za pomocą naturalnej rozmowy.", - "tools.klavis.servers.google-calendar.description": "Google Calendar to usługa zarządzania czasem i planowania", - "tools.klavis.servers.google-calendar.readme": "Zintegruj Kalendarz Google, aby przeglądać, tworzyć i zarządzać wydarzeniami bezproblemowo. Planuj spotkania, ustawiaj przypomnienia, sprawdzaj dostępność i koordynuj czas — wszystko za pomocą poleceń w języku naturalnym.", - "tools.klavis.servers.google-docs.description": "Google Docs to edytor tekstu będący częścią bezpłatnego pakietu Google Docs Editors", - "tools.klavis.servers.google-docs.readme": "Zintegruj się z Dokumentami Google, aby tworzyć, edytować i zarządzać dokumentami. Pisz treści, formatuj tekst, współpracuj w czasie rzeczywistym i uzyskuj dostęp do dokumentów za pomocą naturalnej rozmowy.", - "tools.klavis.servers.google-drive.description": "Google Drive to usługa przechowywania danych w chmurze", - "tools.klavis.servers.google-drive.readme": "Połącz się z Dyskiem Google, aby uzyskać dostęp do plików, organizować je i nimi zarządzać. Wyszukuj dokumenty, przesyłaj pliki, udostępniaj treści i sprawnie poruszaj się po chmurze z pomocą AI.", - "tools.klavis.servers.google-sheets.description": "Google Sheets to aplikacja arkuszy kalkulacyjnych online umożliwiająca tworzenie, edytowanie i współpracę nad arkuszami", - "tools.klavis.servers.google-sheets.readme": "Połącz się z Arkuszami Google, aby odczytywać, zapisywać i analizować dane w arkuszach kalkulacyjnych. Wykonuj obliczenia, generuj raporty, twórz wykresy i zarządzaj danymi tabelarycznymi we współpracy z AI.", - "tools.klavis.servers.hubspot.description": "HubSpot to twórca oprogramowania do marketingu przychodzącego, sprzedaży i obsługi klienta", - "tools.klavis.servers.hubspot.readme": "Zintegruj się z HubSpot, aby zarządzać kontaktami, transakcjami i kampaniami marketingowymi. Uzyskaj dostęp do danych CRM, śledź lejki sprzedażowe, automatyzuj procesy i usprawnij działania sprzedażowe i marketingowe.", - "tools.klavis.servers.jira.description": "Jira to narzędzie do zarządzania projektami i śledzenia zgłoszeń stworzone przez Atlassian", - "tools.klavis.servers.jira.readme": "Zintegruj się z Jira, aby zarządzać zgłoszeniami, śledzić postępy i organizować sprinty. Twórz zgłoszenia, aktualizuj statusy, przeszukuj dane projektowe i usprawniaj procesy deweloperskie za pomocą naturalnej rozmowy.", - "tools.klavis.servers.notion.description": "Notion to aplikacja do produktywności i robienia notatek umożliwiająca współpracę", - "tools.klavis.servers.notion.readme": "Połącz się z Notion, aby uzyskać dostęp do przestrzeni roboczej i nią zarządzać. Twórz strony, przeszukuj treści, aktualizuj bazy danych i organizuj bazę wiedzy — wszystko za pomocą naturalnej rozmowy z asystentem AI.", - "tools.klavis.servers.onedrive.description": "OneDrive to usługa hostingu i synchronizacji plików od Microsoft", - "tools.klavis.servers.onedrive.readme": "Połącz się z OneDrive, aby uzyskać dostęp do plików w chmurze Microsoft i nimi zarządzać. Przesyłaj, pobieraj, udostępniaj pliki, organizuj foldery i współpracuj nad dokumentami z pomocą AI.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail to internetowy pakiet poczty, kontaktów, zadań i kalendarza od Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Zintegruj się z Outlook Mail, aby czytać, wysyłać i zarządzać wiadomościami e-mail Microsoft. Wyszukuj wiadomości, twórz e-maile, zarządzaj folderami i organizuj skrzynkę odbiorczą za pomocą naturalnej rozmowy.", - "tools.klavis.servers.salesforce.description": "Salesforce to wiodąca na świecie platforma CRM, która pomaga firmom łączyć się z klientami, partnerami i potencjalnymi klientami", - "tools.klavis.servers.salesforce.readme": "Połącz się z Salesforce, aby zarządzać relacjami z klientami i danymi sprzedażowymi. Wyszukuj rekordy, aktualizuj szanse sprzedażowe, śledź leady i automatyzuj procesy CRM za pomocą poleceń w języku naturalnym.", - "tools.klavis.servers.slack.description": "Slack to aplikacja do komunikacji biznesowej, która łączy ludzi z potrzebnymi informacjami", - "tools.klavis.servers.slack.readme": "Zintegruj się ze Slackiem, aby wysyłać wiadomości, przeszukiwać rozmowy i zarządzać kanałami. Łącz się z zespołem, automatyzuj komunikację i uzyskuj informacje o przestrzeni roboczej za pomocą języka naturalnego.", - "tools.klavis.servers.supabase.description": "Oficjalny serwer MCP Supabase", - "tools.klavis.servers.supabase.readme": "Zintegruj się z Supabase, aby zarządzać bazą danych i usługami backendowymi. Wykonuj zapytania, zarządzaj uwierzytelnianiem, obsługuj przechowywanie danych i komunikuj się z backendem aplikacji za pomocą naturalnej rozmowy.", - "tools.klavis.servers.whatsapp.description": "Integracja z WhatsApp Business API umożliwiająca wysyłanie wiadomości tekstowych, multimediów i zarządzanie rozmowami z klientami. Idealna do obsługi klienta, kampanii marketingowych i zautomatyzowanych przepływów wiadomości przez oficjalną platformę WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Zintegruj się z WhatsApp Business, aby wysyłać wiadomości, zarządzać rozmowami i angażować klientów. Automatyzuj przepływy wiadomości i obsługuj komunikację za pomocą konwersacyjnej AI.", - "tools.klavis.servers.youtube.description": "YouTube to platforma do udostępniania wideo, na której użytkownicy mogą przesyłać, udostępniać i odkrywać treści. Uzyskaj dostęp do informacji o filmach, transkrypcji i metadanych programowo.", - "tools.klavis.servers.youtube.readme": "Połącz się z YouTube, aby wyszukiwać filmy, uzyskiwać transkrypcje i informacje o wideo. Analizuj treści, wyodrębniaj metadane i odkrywaj filmy za pomocą naturalnej rozmowy.", - "tools.klavis.servers.zendesk.description": "Zendesk to firma oferująca oprogramowanie do obsługi klienta", - "tools.klavis.servers.zendesk.readme": "Zintegruj się z Zendesk, aby zarządzać zgłoszeniami wsparcia i interakcjami z klientami. Twórz, aktualizuj i śledź zgłoszenia, uzyskuj dostęp do danych klientów i usprawniaj działania wsparcia technicznego.", - "tools.klavis.tools": "narzędzia", - "tools.klavis.verifyAuth": "Ukończyłem uwierzytelnienie", + "tools.composio.addServer": "Dodaj serwer", + "tools.composio.authCompleted": "Uwierzytelnienie zakończone", + "tools.composio.authFailed": "Uwierzytelnienie nie powiodło się", + "tools.composio.authRequired": "Wymagane uwierzytelnienie", + "tools.composio.connect": "Połącz", + "tools.composio.connected": "Połączono", + "tools.composio.disconnect": "Odłącz", + "tools.composio.disconnected": "Rozłączono", + "tools.composio.error": "Błąd", + "tools.composio.groupName": "Narzędzia Composio", + "tools.composio.manage": "Zarządzaj Composio", + "tools.composio.manageTitle": "Zarządzanie integracją Composio", + "tools.composio.noServers": "Brak połączonych serwerów", + "tools.composio.notEnabled": "Usługa Composio nie jest włączona", + "tools.composio.oauthRequired": "Proszę zakończyć uwierzytelnienie OAuth w nowym oknie", + "tools.composio.pendingAuth": "Oczekujące uwierzytelnienie", + "tools.composio.serverCreated": "Serwer utworzony pomyślnie", + "tools.composio.serverCreatedFailed": "Nie udało się utworzyć serwera", + "tools.composio.serverRemoved": "Serwer usunięty", + "tools.composio.servers": "serwery", + "tools.composio.servers.airtable.description": "Airtable to platforma baz danych i arkuszy kalkulacyjnych w chmurze, łącząca elastyczność arkusza z mocą bazy danych, umożliwiająca zespołom organizowanie, śledzenie i współpracę nad projektami dzięki konfigurowalnym widokom i zaawansowanej automatyzacji.", + "tools.composio.servers.airtable.readme": "Zintegruj się z Airtable, aby zarządzać bazami danych i przepływami pracy. Wyszukuj rekordy, twórz wpisy, aktualizuj dane i automatyzuj operacje dzięki konfigurowalnym widokom i zaawansowanym funkcjom śledzenia.", + "tools.composio.servers.cal-com.description": "Cal.com to otwartoźródłowa platforma do planowania spotkań, która eliminuje konieczność wymiany wielu e-maili. Zarządzaj typami wydarzeń, rezerwacjami, dostępnością i integruj się z kalendarzami, aby płynnie planować spotkania.", + "tools.composio.servers.cal-com.readme": "Połącz się z Cal.com, aby zarządzać harmonogramem i spotkaniami. Przeglądaj dostępność, rezerwuj spotkania, zarządzaj typami wydarzeń i automatyzuj kalendarz za pomocą naturalnej rozmowy.", + "tools.composio.servers.clickup.description": "ClickUp to kompleksowa platforma do zarządzania projektami i produktywnością, która pomaga zespołom organizować zadania, zarządzać projektami i skutecznie współpracować dzięki konfigurowalnym przepływom pracy i zaawansowanym funkcjom śledzenia.", + "tools.composio.servers.clickup.readme": "Połącz się z ClickUp, aby zarządzać zadaniami, śledzić projekty i organizować pracę. Twórz zadania, aktualizuj statusy, zarządzaj niestandardowymi przepływami pracy i współpracuj z zespołem za pomocą poleceń w języku naturalnym.", + "tools.composio.servers.confluence.description": "Confluence to przestrzeń robocza zespołu, w której wiedza i współpraca się spotykają.", + "tools.composio.servers.confluence.readme": "Połącz się z Confluence, aby uzyskać dostęp do dokumentacji zespołu i nią zarządzać. Wyszukuj strony, twórz treści, organizuj przestrzenie i buduj bazę wiedzy z pomocą konwersacyjnej AI.", + "tools.composio.servers.dropbox.description": "Kompleksowe zarządzanie plikami w chmurze Dropbox. Przesyłaj, pobieraj, organizuj pliki i foldery, zarządzaj udostępnianiem i współpracą, obsługuj wersje plików, twórz żądania plików i wykonuj operacje zbiorcze.", + "tools.composio.servers.dropbox.readme": "Zintegruj się z Dropbox, aby uzyskać dostęp do plików i nimi zarządzać. Przesyłaj, pobieraj, udostępniaj pliki, zarządzaj folderami, obsługuj wersje plików i organizuj przestrzeń w chmurze za pomocą AI.", + "tools.composio.servers.figma.description": "Figma to narzędzie do projektowania interfejsów dla aplikacji internetowych i mobilnych, umożliwiające współpracę.", + "tools.composio.servers.figma.readme": "Połącz się z Figma, aby uzyskać dostęp do plików projektowych i współpracować nad projektami. Przeglądaj projekty, eksportuj zasoby, przeglądaj komponenty i zarządzaj procesem projektowym za pomocą naturalnej rozmowy.", + "tools.composio.servers.github.description": "Ulepszony serwer MCP GitHub", + "tools.composio.servers.github.readme": "Połącz się z GitHub, aby zarządzać repozytoriami, zgłoszeniami, pull requestami i kodem. Wyszukuj kod, przeglądaj zmiany, twórz gałęzie i współpracuj nad projektami programistycznymi z pomocą konwersacyjnej AI.", + "tools.composio.servers.gmail.description": "Gmail to bezpłatna usługa e-mail od Google", + "tools.composio.servers.gmail.readme": "Wykorzystaj możliwości Gmaila bezpośrednio w swoim asystencie AI. Czytaj, twórz i wysyłaj e-maile, przeszukuj skrzynkę odbiorczą, zarządzaj etykietami i organizuj komunikację — wszystko za pomocą naturalnej rozmowy.", + "tools.composio.servers.google-calendar.description": "Google Calendar to usługa zarządzania czasem i planowania", + "tools.composio.servers.google-calendar.readme": "Zintegruj Kalendarz Google, aby przeglądać, tworzyć i zarządzać wydarzeniami bezproblemowo. Planuj spotkania, ustawiaj przypomnienia, sprawdzaj dostępność i koordynuj czas — wszystko za pomocą poleceń w języku naturalnym.", + "tools.composio.servers.google-docs.description": "Google Docs to edytor tekstu będący częścią bezpłatnego pakietu Google Docs Editors", + "tools.composio.servers.google-docs.readme": "Zintegruj się z Dokumentami Google, aby tworzyć, edytować i zarządzać dokumentami. Pisz treści, formatuj tekst, współpracuj w czasie rzeczywistym i uzyskuj dostęp do dokumentów za pomocą naturalnej rozmowy.", + "tools.composio.servers.google-drive.description": "Google Drive to usługa przechowywania danych w chmurze", + "tools.composio.servers.google-drive.readme": "Połącz się z Dyskiem Google, aby uzyskać dostęp do plików, organizować je i nimi zarządzać. Wyszukuj dokumenty, przesyłaj pliki, udostępniaj treści i sprawnie poruszaj się po chmurze z pomocą AI.", + "tools.composio.servers.google-sheets.description": "Google Sheets to aplikacja arkuszy kalkulacyjnych online umożliwiająca tworzenie, edytowanie i współpracę nad arkuszami", + "tools.composio.servers.google-sheets.readme": "Połącz się z Arkuszami Google, aby odczytywać, zapisywać i analizować dane w arkuszach kalkulacyjnych. Wykonuj obliczenia, generuj raporty, twórz wykresy i zarządzaj danymi tabelarycznymi we współpracy z AI.", + "tools.composio.servers.hubspot.description": "HubSpot to twórca oprogramowania do marketingu przychodzącego, sprzedaży i obsługi klienta", + "tools.composio.servers.hubspot.readme": "Zintegruj się z HubSpot, aby zarządzać kontaktami, transakcjami i kampaniami marketingowymi. Uzyskaj dostęp do danych CRM, śledź lejki sprzedażowe, automatyzuj procesy i usprawnij działania sprzedażowe i marketingowe.", + "tools.composio.servers.jira.description": "Jira to narzędzie do zarządzania projektami i śledzenia zgłoszeń stworzone przez Atlassian", + "tools.composio.servers.jira.readme": "Zintegruj się z Jira, aby zarządzać zgłoszeniami, śledzić postępy i organizować sprinty. Twórz zgłoszenia, aktualizuj statusy, przeszukuj dane projektowe i usprawniaj procesy deweloperskie za pomocą naturalnej rozmowy.", + "tools.composio.servers.notion.description": "Notion to aplikacja do produktywności i robienia notatek umożliwiająca współpracę", + "tools.composio.servers.notion.readme": "Połącz się z Notion, aby uzyskać dostęp do przestrzeni roboczej i nią zarządzać. Twórz strony, przeszukuj treści, aktualizuj bazy danych i organizuj bazę wiedzy — wszystko za pomocą naturalnej rozmowy z asystentem AI.", + "tools.composio.servers.onedrive.description": "OneDrive to usługa hostingu i synchronizacji plików od Microsoft", + "tools.composio.servers.onedrive.readme": "Połącz się z OneDrive, aby uzyskać dostęp do plików w chmurze Microsoft i nimi zarządzać. Przesyłaj, pobieraj, udostępniaj pliki, organizuj foldery i współpracuj nad dokumentami z pomocą AI.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail to internetowy pakiet poczty, kontaktów, zadań i kalendarza od Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Zintegruj się z Outlook Mail, aby czytać, wysyłać i zarządzać wiadomościami e-mail Microsoft. Wyszukuj wiadomości, twórz e-maile, zarządzaj folderami i organizuj skrzynkę odbiorczą za pomocą naturalnej rozmowy.", + "tools.composio.servers.salesforce.description": "Salesforce to wiodąca na świecie platforma CRM, która pomaga firmom łączyć się z klientami, partnerami i potencjalnymi klientami", + "tools.composio.servers.salesforce.readme": "Połącz się z Salesforce, aby zarządzać relacjami z klientami i danymi sprzedażowymi. Wyszukuj rekordy, aktualizuj szanse sprzedażowe, śledź leady i automatyzuj procesy CRM za pomocą poleceń w języku naturalnym.", + "tools.composio.servers.slack.description": "Slack to aplikacja do komunikacji biznesowej, która łączy ludzi z potrzebnymi informacjami", + "tools.composio.servers.slack.readme": "Zintegruj się ze Slackiem, aby wysyłać wiadomości, przeszukiwać rozmowy i zarządzać kanałami. Łącz się z zespołem, automatyzuj komunikację i uzyskuj informacje o przestrzeni roboczej za pomocą języka naturalnego.", + "tools.composio.servers.supabase.description": "Oficjalny serwer MCP Supabase", + "tools.composio.servers.supabase.readme": "Zintegruj się z Supabase, aby zarządzać bazą danych i usługami backendowymi. Wykonuj zapytania, zarządzaj uwierzytelnianiem, obsługuj przechowywanie danych i komunikuj się z backendem aplikacji za pomocą naturalnej rozmowy.", + "tools.composio.servers.whatsapp.description": "Integracja z WhatsApp Business API umożliwiająca wysyłanie wiadomości tekstowych, multimediów i zarządzanie rozmowami z klientami. Idealna do obsługi klienta, kampanii marketingowych i zautomatyzowanych przepływów wiadomości przez oficjalną platformę WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Zintegruj się z WhatsApp Business, aby wysyłać wiadomości, zarządzać rozmowami i angażować klientów. Automatyzuj przepływy wiadomości i obsługuj komunikację za pomocą konwersacyjnej AI.", + "tools.composio.servers.youtube.description": "YouTube to platforma do udostępniania wideo, na której użytkownicy mogą przesyłać, udostępniać i odkrywać treści. Uzyskaj dostęp do informacji o filmach, transkrypcji i metadanych programowo.", + "tools.composio.servers.youtube.readme": "Połącz się z YouTube, aby wyszukiwać filmy, uzyskiwać transkrypcje i informacje o wideo. Analizuj treści, wyodrębniaj metadane i odkrywaj filmy za pomocą naturalnej rozmowy.", + "tools.composio.servers.zendesk.description": "Zendesk to firma oferująca oprogramowanie do obsługi klienta", + "tools.composio.servers.zendesk.readme": "Zintegruj się z Zendesk, aby zarządzać zgłoszeniami wsparcia i interakcjami z klientami. Twórz, aktualizuj i śledź zgłoszenia, uzyskuj dostęp do danych klientów i usprawniaj działania wsparcia technicznego.", + "tools.composio.tools": "narzędzia", + "tools.composio.verifyAuth": "Ukończyłem uwierzytelnienie", "tools.lobehubSkill.authorize": "Autoryzuj", "tools.lobehubSkill.connect": "Połącz", "tools.lobehubSkill.connected": "Połączono", diff --git a/locales/pt-BR/setting.json b/locales/pt-BR/setting.json index aa367f816bb..4e331eafe4c 100644 --- a/locales/pt-BR/setting.json +++ b/locales/pt-BR/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Desinstalar {{name}}", "tools.builtins.uninstalled": "Desinstalado", "tools.disabled": "O modelo atual não suporta chamadas de função e não pode usar a habilidade", - "tools.klavis.addServer": "Adicionar Servidor", - "tools.klavis.authCompleted": "Autenticação Concluída", - "tools.klavis.authFailed": "Falha na Autenticação", - "tools.klavis.authRequired": "Autenticação Necessária", - "tools.klavis.connect": "Conectar", - "tools.klavis.connected": "Conectado", - "tools.klavis.disconnect": "Desconectar", - "tools.klavis.disconnected": "Desconectado", - "tools.klavis.error": "Erro", - "tools.klavis.groupName": "Ferramentas Klavis", - "tools.klavis.manage": "Gerenciar Klavis", - "tools.klavis.manageTitle": "Gerenciar Integração Klavis", - "tools.klavis.noServers": "Nenhum servidor conectado", - "tools.klavis.notEnabled": "Serviço Klavis não ativado", - "tools.klavis.oauthRequired": "Por favor, conclua a autenticação OAuth na nova janela", - "tools.klavis.pendingAuth": "Autenticação Pendente", - "tools.klavis.remove": "Remover", - "tools.klavis.removeConfirm.desc": "{{name}} será removido permanentemente dos seus serviços conectados. Esta ação não pode ser desfeita.", - "tools.klavis.removeConfirm.title": "Remover {{name}}?", - "tools.klavis.serverCreated": "Servidor criado com sucesso", - "tools.klavis.serverCreatedFailed": "Falha ao criar servidor", - "tools.klavis.serverRemoved": "Servidor removido", - "tools.klavis.servers": "servidores", - "tools.klavis.servers.airtable.description": "O Airtable é uma plataforma de banco de dados e planilhas baseada na nuvem que combina a flexibilidade de uma planilha com o poder de um banco de dados, permitindo que equipes organizem, acompanhem e colaborem em projetos com visualizações personalizáveis e recursos avançados de automação.", - "tools.klavis.servers.airtable.readme": "Integre com o Airtable para gerenciar seus bancos de dados e fluxos de trabalho. Consulte registros, crie entradas, atualize dados e automatize operações com visualizações personalizáveis e recursos avançados de acompanhamento.", - "tools.klavis.servers.cal-com.description": "O Cal.com é uma plataforma de agendamento de código aberto que ajuda você a marcar reuniões sem trocas intermináveis de e-mails. Gerencie tipos de eventos, reservas, disponibilidade e integre com calendários para um agendamento de compromissos sem complicações.", - "tools.klavis.servers.cal-com.readme": "Conecte-se ao Cal.com para gerenciar sua agenda e compromissos. Veja disponibilidades, agende reuniões, gerencie tipos de eventos e automatize seu calendário por meio de conversas naturais.", - "tools.klavis.servers.clickup.description": "O ClickUp é uma plataforma abrangente de gerenciamento de projetos e produtividade que ajuda equipes a organizar tarefas, gerenciar projetos e colaborar de forma eficaz com fluxos de trabalho personalizáveis e recursos avançados de acompanhamento.", - "tools.klavis.servers.clickup.readme": "Conecte-se ao ClickUp para gerenciar tarefas, acompanhar projetos e organizar seu trabalho. Crie tarefas, atualize status, gerencie fluxos de trabalho personalizados e colabore com sua equipe usando comandos em linguagem natural.", - "tools.klavis.servers.confluence.description": "O Confluence é um espaço de trabalho em equipe onde conhecimento e colaboração se encontram.", - "tools.klavis.servers.confluence.readme": "Conecte-se ao Confluence para acessar e gerenciar a documentação da equipe. Pesquise páginas, crie conteúdos, organize espaços e construa sua base de conhecimento com a ajuda de IA conversacional.", - "tools.klavis.servers.dropbox.description": "Solução completa de gerenciamento de arquivos para o armazenamento em nuvem do Dropbox. Envie, baixe, organize arquivos e pastas, gerencie compartilhamentos e colaborações, controle versões de arquivos, crie solicitações de arquivos e realize operações em lote nos seus arquivos e pastas do Dropbox.", - "tools.klavis.servers.dropbox.readme": "Integre com o Dropbox para acessar e gerenciar seus arquivos. Envie, baixe, compartilhe arquivos, gerencie pastas, controle versões e organize seu armazenamento em nuvem com assistência de IA.", - "tools.klavis.servers.figma.description": "O Figma é uma ferramenta colaborativa de design de interfaces para aplicações web e móveis.", - "tools.klavis.servers.figma.readme": "Conecte-se ao Figma para acessar arquivos de design e colaborar em projetos. Visualize designs, exporte recursos, navegue por componentes e gerencie seu fluxo de trabalho de design por meio de conversas naturais.", - "tools.klavis.servers.github.description": "Servidor MCP GitHub aprimorado", - "tools.klavis.servers.github.readme": "Conecte-se ao GitHub para gerenciar repositórios, issues, pull requests e código. Pesquise código, revise alterações, crie branches e colabore em projetos de desenvolvimento de software com IA conversacional.", - "tools.klavis.servers.gmail.description": "O Gmail é um serviço de e-mail gratuito fornecido pelo Google", - "tools.klavis.servers.gmail.readme": "Traga o poder do Gmail diretamente para seu assistente de IA. Leia, escreva e envie e-mails, pesquise na caixa de entrada, gerencie marcadores e organize suas comunicações — tudo por meio de conversas naturais.", - "tools.klavis.servers.google-calendar.description": "O Google Agenda é um serviço de calendário para gerenciamento de tempo e agendamentos", - "tools.klavis.servers.google-calendar.readme": "Integre o Google Agenda para visualizar, criar e gerenciar seus eventos com facilidade. Agende reuniões, defina lembretes, verifique disponibilidades e coordene seu tempo com comandos em linguagem natural.", - "tools.klavis.servers.google-docs.description": "O Google Docs é um processador de texto incluído na suíte gratuita de editores do Google baseada na web", - "tools.klavis.servers.google-docs.readme": "Integre com o Google Docs para criar, editar e gerenciar documentos. Escreva conteúdos, formate textos, colabore em tempo real e acesse seus documentos por meio de conversas naturais.", - "tools.klavis.servers.google-drive.description": "O Google Drive é um serviço de armazenamento em nuvem", - "tools.klavis.servers.google-drive.readme": "Conecte-se ao Google Drive para acessar, organizar e gerenciar seus arquivos. Pesquise documentos, envie arquivos, compartilhe conteúdos e navegue pelo seu armazenamento em nuvem com ajuda da IA.", - "tools.klavis.servers.google-sheets.description": "O Google Sheets é um aplicativo de planilhas baseado na web que permite aos usuários criar, editar e colaborar em planilhas online", - "tools.klavis.servers.google-sheets.readme": "Conecte-se ao Google Sheets para ler, escrever e analisar dados em planilhas. Realize cálculos, gere relatórios, crie gráficos e gerencie dados tabulares colaborativamente com assistência de IA.", - "tools.klavis.servers.hubspot.description": "O HubSpot é um desenvolvedor e fornecedor de softwares para marketing de atração, vendas e atendimento ao cliente", - "tools.klavis.servers.hubspot.readme": "Integre com o HubSpot para gerenciar contatos, negócios e campanhas de marketing. Acesse dados de CRM, acompanhe funis de vendas, automatize fluxos de trabalho e otimize suas operações de vendas e marketing.", - "tools.klavis.servers.jira.description": "O Jira é uma ferramenta de gerenciamento de projetos e rastreamento de issues desenvolvida pela Atlassian", - "tools.klavis.servers.jira.readme": "Integre com o Jira para gerenciar issues, acompanhar progresso e organizar sprints. Crie tickets, atualize status, consulte dados de projetos e otimize seu fluxo de desenvolvimento com conversas naturais.", - "tools.klavis.servers.notion.description": "O Notion é um aplicativo colaborativo de produtividade e anotações", - "tools.klavis.servers.notion.readme": "Conecte-se ao Notion para acessar e gerenciar seu espaço de trabalho. Crie páginas, pesquise conteúdos, atualize bancos de dados e organize sua base de conhecimento com a ajuda do seu assistente de IA.", - "tools.klavis.servers.onedrive.description": "O OneDrive é um serviço de hospedagem e sincronização de arquivos operado pela Microsoft", - "tools.klavis.servers.onedrive.readme": "Conecte-se ao OneDrive para acessar e gerenciar seus arquivos na nuvem da Microsoft. Envie, baixe, compartilhe arquivos, organize pastas e colabore em documentos com assistência baseada em IA.", - "tools.klavis.servers.outlook-mail.description": "O Outlook Mail é um conjunto de serviços baseados na web da Microsoft que inclui e-mail, contatos, tarefas e calendário.", - "tools.klavis.servers.outlook-mail.readme": "Integre com o Outlook Mail para ler, enviar e gerenciar seus e-mails da Microsoft. Pesquise mensagens, escreva e-mails, gerencie pastas e organize sua caixa de entrada com conversas naturais.", - "tools.klavis.servers.salesforce.description": "O Salesforce é a principal plataforma de gerenciamento de relacionamento com o cliente (CRM) do mundo, ajudando empresas a se conectarem com clientes, parceiros e potenciais clientes", - "tools.klavis.servers.salesforce.readme": "Conecte-se ao Salesforce para gerenciar relacionamentos com clientes e dados de vendas. Consulte registros, atualize oportunidades, acompanhe leads e automatize fluxos de trabalho de CRM com comandos em linguagem natural.", - "tools.klavis.servers.slack.description": "O Slack é um aplicativo de mensagens para empresas que conecta pessoas às informações de que precisam", - "tools.klavis.servers.slack.readme": "Integre com o Slack para enviar mensagens, pesquisar conversas e gerenciar canais. Conecte-se com sua equipe, automatize fluxos de comunicação e acesse informações do espaço de trabalho com linguagem natural.", - "tools.klavis.servers.supabase.description": "Servidor MCP oficial do Supabase", - "tools.klavis.servers.supabase.readme": "Integre com o Supabase para gerenciar seu banco de dados e serviços de backend. Consulte dados, gerencie autenticação, controle armazenamento e interaja com o backend da sua aplicação por meio de conversas naturais.", - "tools.klavis.servers.whatsapp.description": "Integração com a API do WhatsApp Business que permite o envio de mensagens de texto, mídias e o gerenciamento de conversas com clientes. Ideal para suporte ao cliente, campanhas de marketing e fluxos de mensagens automatizadas por meio da plataforma oficial do WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Integre com o WhatsApp Business para enviar mensagens, gerenciar conversas e interagir com clientes. Automatize fluxos de mensagens e gerencie comunicações com IA conversacional.", - "tools.klavis.servers.youtube.description": "O YouTube é uma plataforma de compartilhamento de vídeos onde os usuários podem enviar, compartilhar e descobrir conteúdo. Acesse informações de vídeos, transcrições e metadados programaticamente.", - "tools.klavis.servers.youtube.readme": "Conecte-se ao YouTube para pesquisar vídeos, acessar transcrições e obter informações sobre vídeos. Analise conteúdos, extraia metadados e descubra vídeos por meio de conversas naturais.", - "tools.klavis.servers.zendesk.description": "O Zendesk é uma empresa de software de atendimento ao cliente", - "tools.klavis.servers.zendesk.readme": "Integre com o Zendesk para gerenciar tickets de suporte e interações com clientes. Crie, atualize e acompanhe solicitações de suporte, acesse dados de clientes e otimize suas operações de atendimento.", - "tools.klavis.tools": "ferramentas", - "tools.klavis.verifyAuth": "Concluí a autenticação", + "tools.composio.addServer": "Adicionar Servidor", + "tools.composio.authCompleted": "Autenticação Concluída", + "tools.composio.authFailed": "Falha na Autenticação", + "tools.composio.authRequired": "Autenticação Necessária", + "tools.composio.connect": "Conectar", + "tools.composio.connected": "Conectado", + "tools.composio.disconnect": "Desconectar", + "tools.composio.disconnected": "Desconectado", + "tools.composio.error": "Erro", + "tools.composio.groupName": "Ferramentas Composio", + "tools.composio.manage": "Gerenciar Composio", + "tools.composio.manageTitle": "Gerenciar Integração Composio", + "tools.composio.noServers": "Nenhum servidor conectado", + "tools.composio.notEnabled": "Serviço Composio não ativado", + "tools.composio.oauthRequired": "Por favor, conclua a autenticação OAuth na nova janela", + "tools.composio.pendingAuth": "Autenticação Pendente", + "tools.composio.serverCreated": "Servidor criado com sucesso", + "tools.composio.serverCreatedFailed": "Falha ao criar servidor", + "tools.composio.serverRemoved": "Servidor removido", + "tools.composio.servers": "servidores", + "tools.composio.servers.airtable.description": "O Airtable é uma plataforma de banco de dados e planilhas baseada na nuvem que combina a flexibilidade de uma planilha com o poder de um banco de dados, permitindo que equipes organizem, acompanhem e colaborem em projetos com visualizações personalizáveis e recursos avançados de automação.", + "tools.composio.servers.airtable.readme": "Integre com o Airtable para gerenciar seus bancos de dados e fluxos de trabalho. Consulte registros, crie entradas, atualize dados e automatize operações com visualizações personalizáveis e recursos avançados de acompanhamento.", + "tools.composio.servers.cal-com.description": "O Cal.com é uma plataforma de agendamento de código aberto que ajuda você a marcar reuniões sem trocas intermináveis de e-mails. Gerencie tipos de eventos, reservas, disponibilidade e integre com calendários para um agendamento de compromissos sem complicações.", + "tools.composio.servers.cal-com.readme": "Conecte-se ao Cal.com para gerenciar sua agenda e compromissos. Veja disponibilidades, agende reuniões, gerencie tipos de eventos e automatize seu calendário por meio de conversas naturais.", + "tools.composio.servers.clickup.description": "O ClickUp é uma plataforma abrangente de gerenciamento de projetos e produtividade que ajuda equipes a organizar tarefas, gerenciar projetos e colaborar de forma eficaz com fluxos de trabalho personalizáveis e recursos avançados de acompanhamento.", + "tools.composio.servers.clickup.readme": "Conecte-se ao ClickUp para gerenciar tarefas, acompanhar projetos e organizar seu trabalho. Crie tarefas, atualize status, gerencie fluxos de trabalho personalizados e colabore com sua equipe usando comandos em linguagem natural.", + "tools.composio.servers.confluence.description": "O Confluence é um espaço de trabalho em equipe onde conhecimento e colaboração se encontram.", + "tools.composio.servers.confluence.readme": "Conecte-se ao Confluence para acessar e gerenciar a documentação da equipe. Pesquise páginas, crie conteúdos, organize espaços e construa sua base de conhecimento com a ajuda de IA conversacional.", + "tools.composio.servers.dropbox.description": "Solução completa de gerenciamento de arquivos para o armazenamento em nuvem do Dropbox. Envie, baixe, organize arquivos e pastas, gerencie compartilhamentos e colaborações, controle versões de arquivos, crie solicitações de arquivos e realize operações em lote nos seus arquivos e pastas do Dropbox.", + "tools.composio.servers.dropbox.readme": "Integre com o Dropbox para acessar e gerenciar seus arquivos. Envie, baixe, compartilhe arquivos, gerencie pastas, controle versões e organize seu armazenamento em nuvem com assistência de IA.", + "tools.composio.servers.figma.description": "O Figma é uma ferramenta colaborativa de design de interfaces para aplicações web e móveis.", + "tools.composio.servers.figma.readme": "Conecte-se ao Figma para acessar arquivos de design e colaborar em projetos. Visualize designs, exporte recursos, navegue por componentes e gerencie seu fluxo de trabalho de design por meio de conversas naturais.", + "tools.composio.servers.github.description": "Servidor MCP GitHub aprimorado", + "tools.composio.servers.github.readme": "Conecte-se ao GitHub para gerenciar repositórios, issues, pull requests e código. Pesquise código, revise alterações, crie branches e colabore em projetos de desenvolvimento de software com IA conversacional.", + "tools.composio.servers.gmail.description": "O Gmail é um serviço de e-mail gratuito fornecido pelo Google", + "tools.composio.servers.gmail.readme": "Traga o poder do Gmail diretamente para seu assistente de IA. Leia, escreva e envie e-mails, pesquise na caixa de entrada, gerencie marcadores e organize suas comunicações — tudo por meio de conversas naturais.", + "tools.composio.servers.google-calendar.description": "O Google Agenda é um serviço de calendário para gerenciamento de tempo e agendamentos", + "tools.composio.servers.google-calendar.readme": "Integre o Google Agenda para visualizar, criar e gerenciar seus eventos com facilidade. Agende reuniões, defina lembretes, verifique disponibilidades e coordene seu tempo com comandos em linguagem natural.", + "tools.composio.servers.google-docs.description": "O Google Docs é um processador de texto incluído na suíte gratuita de editores do Google baseada na web", + "tools.composio.servers.google-docs.readme": "Integre com o Google Docs para criar, editar e gerenciar documentos. Escreva conteúdos, formate textos, colabore em tempo real e acesse seus documentos por meio de conversas naturais.", + "tools.composio.servers.google-drive.description": "O Google Drive é um serviço de armazenamento em nuvem", + "tools.composio.servers.google-drive.readme": "Conecte-se ao Google Drive para acessar, organizar e gerenciar seus arquivos. Pesquise documentos, envie arquivos, compartilhe conteúdos e navegue pelo seu armazenamento em nuvem com ajuda da IA.", + "tools.composio.servers.google-sheets.description": "O Google Sheets é um aplicativo de planilhas baseado na web que permite aos usuários criar, editar e colaborar em planilhas online", + "tools.composio.servers.google-sheets.readme": "Conecte-se ao Google Sheets para ler, escrever e analisar dados em planilhas. Realize cálculos, gere relatórios, crie gráficos e gerencie dados tabulares colaborativamente com assistência de IA.", + "tools.composio.servers.hubspot.description": "O HubSpot é um desenvolvedor e fornecedor de softwares para marketing de atração, vendas e atendimento ao cliente", + "tools.composio.servers.hubspot.readme": "Integre com o HubSpot para gerenciar contatos, negócios e campanhas de marketing. Acesse dados de CRM, acompanhe funis de vendas, automatize fluxos de trabalho e otimize suas operações de vendas e marketing.", + "tools.composio.servers.jira.description": "O Jira é uma ferramenta de gerenciamento de projetos e rastreamento de issues desenvolvida pela Atlassian", + "tools.composio.servers.jira.readme": "Integre com o Jira para gerenciar issues, acompanhar progresso e organizar sprints. Crie tickets, atualize status, consulte dados de projetos e otimize seu fluxo de desenvolvimento com conversas naturais.", + "tools.composio.servers.notion.description": "O Notion é um aplicativo colaborativo de produtividade e anotações", + "tools.composio.servers.notion.readme": "Conecte-se ao Notion para acessar e gerenciar seu espaço de trabalho. Crie páginas, pesquise conteúdos, atualize bancos de dados e organize sua base de conhecimento com a ajuda do seu assistente de IA.", + "tools.composio.servers.onedrive.description": "O OneDrive é um serviço de hospedagem e sincronização de arquivos operado pela Microsoft", + "tools.composio.servers.onedrive.readme": "Conecte-se ao OneDrive para acessar e gerenciar seus arquivos na nuvem da Microsoft. Envie, baixe, compartilhe arquivos, organize pastas e colabore em documentos com assistência baseada em IA.", + "tools.composio.servers.outlook-mail.description": "O Outlook Mail é um conjunto de serviços baseados na web da Microsoft que inclui e-mail, contatos, tarefas e calendário.", + "tools.composio.servers.outlook-mail.readme": "Integre com o Outlook Mail para ler, enviar e gerenciar seus e-mails da Microsoft. Pesquise mensagens, escreva e-mails, gerencie pastas e organize sua caixa de entrada com conversas naturais.", + "tools.composio.servers.salesforce.description": "O Salesforce é a principal plataforma de gerenciamento de relacionamento com o cliente (CRM) do mundo, ajudando empresas a se conectarem com clientes, parceiros e potenciais clientes", + "tools.composio.servers.salesforce.readme": "Conecte-se ao Salesforce para gerenciar relacionamentos com clientes e dados de vendas. Consulte registros, atualize oportunidades, acompanhe leads e automatize fluxos de trabalho de CRM com comandos em linguagem natural.", + "tools.composio.servers.slack.description": "O Slack é um aplicativo de mensagens para empresas que conecta pessoas às informações de que precisam", + "tools.composio.servers.slack.readme": "Integre com o Slack para enviar mensagens, pesquisar conversas e gerenciar canais. Conecte-se com sua equipe, automatize fluxos de comunicação e acesse informações do espaço de trabalho com linguagem natural.", + "tools.composio.servers.supabase.description": "Servidor MCP oficial do Supabase", + "tools.composio.servers.supabase.readme": "Integre com o Supabase para gerenciar seu banco de dados e serviços de backend. Consulte dados, gerencie autenticação, controle armazenamento e interaja com o backend da sua aplicação por meio de conversas naturais.", + "tools.composio.servers.whatsapp.description": "Integração com a API do WhatsApp Business que permite o envio de mensagens de texto, mídias e o gerenciamento de conversas com clientes. Ideal para suporte ao cliente, campanhas de marketing e fluxos de mensagens automatizadas por meio da plataforma oficial do WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Integre com o WhatsApp Business para enviar mensagens, gerenciar conversas e interagir com clientes. Automatize fluxos de mensagens e gerencie comunicações com IA conversacional.", + "tools.composio.servers.youtube.description": "O YouTube é uma plataforma de compartilhamento de vídeos onde os usuários podem enviar, compartilhar e descobrir conteúdo. Acesse informações de vídeos, transcrições e metadados programaticamente.", + "tools.composio.servers.youtube.readme": "Conecte-se ao YouTube para pesquisar vídeos, acessar transcrições e obter informações sobre vídeos. Analise conteúdos, extraia metadados e descubra vídeos por meio de conversas naturais.", + "tools.composio.servers.zendesk.description": "O Zendesk é uma empresa de software de atendimento ao cliente", + "tools.composio.servers.zendesk.readme": "Integre com o Zendesk para gerenciar tickets de suporte e interações com clientes. Crie, atualize e acompanhe solicitações de suporte, acesse dados de clientes e otimize suas operações de atendimento.", + "tools.composio.tools": "ferramentas", + "tools.composio.verifyAuth": "Concluí a autenticação", "tools.lobehubSkill.authorize": "Autorizar", "tools.lobehubSkill.connect": "Conectar", "tools.lobehubSkill.connected": "Conectado", diff --git a/locales/ru-RU/setting.json b/locales/ru-RU/setting.json index 317eeeae09f..4c21d8e1809 100644 --- a/locales/ru-RU/setting.json +++ b/locales/ru-RU/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Удалить {{name}}", "tools.builtins.uninstalled": "Удалено", "tools.disabled": "Текущая модель не поддерживает вызов функций и не может использовать навык", - "tools.klavis.addServer": "Добавить сервер", - "tools.klavis.authCompleted": "Аутентификация завершена", - "tools.klavis.authFailed": "Ошибка аутентификации", - "tools.klavis.authRequired": "Требуется аутентификация", - "tools.klavis.connect": "Подключить", - "tools.klavis.connected": "Подключено", - "tools.klavis.disconnect": "Отключить", - "tools.klavis.disconnected": "Отключено", - "tools.klavis.error": "Ошибка", - "tools.klavis.groupName": "Инструменты Klavis", - "tools.klavis.manage": "Управление Klavis", - "tools.klavis.manageTitle": "Управление интеграцией Klavis", - "tools.klavis.noServers": "Нет подключённых серверов", - "tools.klavis.notEnabled": "Служба Klavis не включена", - "tools.klavis.oauthRequired": "Пожалуйста, завершите OAuth-аутентификацию в новом окне", - "tools.klavis.pendingAuth": "Ожидание аутентификации", - "tools.klavis.remove": "Удалить", - "tools.klavis.removeConfirm.desc": "{{name}} будет навсегда удален из ваших подключенных сервисов. Это действие нельзя отменить.", - "tools.klavis.removeConfirm.title": "Удалить {{name}}?", - "tools.klavis.serverCreated": "Сервер успешно создан", - "tools.klavis.serverCreatedFailed": "Не удалось создать сервер", - "tools.klavis.serverRemoved": "Сервер удалён", - "tools.klavis.servers": "серверы", - "tools.klavis.servers.airtable.description": "Airtable — это облачная платформа баз данных и электронных таблиц, сочетающая гибкость таблиц с мощью баз данных, позволяя командам организовывать, отслеживать и совместно работать над проектами с настраиваемыми представлениями и мощной автоматизацией.", - "tools.klavis.servers.airtable.readme": "Интеграция с Airtable для управления базами данных и рабочими процессами. Выполняйте запросы, создавайте записи, обновляйте данные и автоматизируйте операции с помощью настраиваемых представлений и мощных функций отслеживания.", - "tools.klavis.servers.cal-com.description": "Cal.com — это платформа с открытым исходным кодом для планирования встреч без необходимости обмена множеством писем. Управляйте типами событий, бронированиями, доступностью и интеграцией с календарями для удобного планирования.", - "tools.klavis.servers.cal-com.readme": "Подключитесь к Cal.com для управления расписанием и встречами. Просматривайте доступность, бронируйте встречи, управляйте типами событий и автоматизируйте календарь с помощью естественного языка.", - "tools.klavis.servers.clickup.description": "ClickUp — это универсальная платформа управления проектами и повышения продуктивности, помогающая командам организовывать задачи, управлять проектами и эффективно сотрудничать с помощью настраиваемых рабочих процессов и мощных инструментов отслеживания.", - "tools.klavis.servers.clickup.readme": "Интеграция с ClickUp для управления задачами, отслеживания проектов и организации работы. Создавайте задачи, обновляйте статусы, управляйте пользовательскими рабочими процессами и сотрудничайте с командой с помощью команд на естественном языке.", - "tools.klavis.servers.confluence.description": "Confluence — это рабочее пространство команды, где сочетаются знания и сотрудничество.", - "tools.klavis.servers.confluence.readme": "Интеграция с Confluence для доступа и управления командной документацией. Ищите страницы, создавайте контент, организуйте пространства и развивайте базу знаний с помощью ИИ-ассистента.", - "tools.klavis.servers.dropbox.description": "Полноценное решение для управления файлами в облачном хранилище Dropbox. Загружайте, скачивайте, организуйте файлы и папки, управляйте доступом и совместной работой, обрабатывайте версии файлов, создавайте запросы на файлы и выполняйте пакетные операции.", - "tools.klavis.servers.dropbox.readme": "Интеграция с Dropbox для доступа и управления файлами. Загружайте, скачивайте, делитесь файлами, управляйте папками, отслеживайте версии и организуйте облачное хранилище с помощью ИИ.", - "tools.klavis.servers.figma.description": "Figma — это инструмент совместного проектирования интерфейсов для веб- и мобильных приложений.", - "tools.klavis.servers.figma.readme": "Подключитесь к Figma для доступа к дизайн-файлам и совместной работы над проектами. Просматривайте макеты, экспортируйте ресурсы, изучайте компоненты и управляйте рабочим процессом дизайна через естественный диалог.", - "tools.klavis.servers.github.description": "Улучшенный сервер GitHub MCP", - "tools.klavis.servers.github.readme": "Интеграция с GitHub для управления репозиториями, задачами, pull-запросами и кодом. Ищите код, просматривайте изменения, создавайте ветки и сотрудничайте в разработке программного обеспечения с помощью ИИ.", - "tools.klavis.servers.gmail.description": "Gmail — это бесплатный почтовый сервис от Google", - "tools.klavis.servers.gmail.readme": "Используйте возможности Gmail прямо в вашем ИИ-ассистенте. Читайте, создавайте и отправляйте письма, ищите в почтовом ящике, управляйте ярлыками и организуйте коммуникации — всё через естественный язык.", - "tools.klavis.servers.google-calendar.description": "Google Календарь — это сервис управления временем и расписанием", - "tools.klavis.servers.google-calendar.readme": "Интеграция с Google Календарём для просмотра, создания и управления событиями. Планируйте встречи, устанавливайте напоминания, проверяйте доступность и координируйте своё время с помощью команд на естественном языке.", - "tools.klavis.servers.google-docs.description": "Google Документы — это текстовый редактор, входящий в бесплатный веб-пакет Google Docs Editors", - "tools.klavis.servers.google-docs.readme": "Интеграция с Google Документами для создания, редактирования и управления файлами. Пишите тексты, форматируйте, сотрудничайте в реальном времени и получайте доступ к документам через диалог с ИИ.", - "tools.klavis.servers.google-drive.description": "Google Диск — это облачное хранилище", - "tools.klavis.servers.google-drive.readme": "Подключитесь к Google Диску для доступа, организации и управления файлами. Ищите документы, загружайте файлы, делитесь контентом и эффективно управляйте облачным хранилищем с помощью ИИ.", - "tools.klavis.servers.google-sheets.description": "Google Таблицы — это веб-приложение для создания, редактирования и совместной работы с электронными таблицами", - "tools.klavis.servers.google-sheets.readme": "Интеграция с Google Таблицами для чтения, записи и анализа данных. Выполняйте вычисления, создавайте отчёты, строите графики и управляйте табличными данными совместно с ИИ.", - "tools.klavis.servers.hubspot.description": "HubSpot — это разработчик программного обеспечения для входящего маркетинга, продаж и обслуживания клиентов", - "tools.klavis.servers.hubspot.readme": "Интеграция с HubSpot для управления контактами, сделками и маркетинговыми кампаниями. Получайте доступ к CRM-данным, отслеживайте воронки продаж, автоматизируйте процессы и оптимизируйте маркетинг и продажи.", - "tools.klavis.servers.jira.description": "Jira — это инструмент управления проектами и отслеживания задач от Atlassian", - "tools.klavis.servers.jira.readme": "Интеграция с Jira для управления задачами, отслеживания прогресса и организации спринтов. Создавайте тикеты, обновляйте статусы, запрашивайте данные проектов и оптимизируйте рабочий процесс разработки через диалог.", - "tools.klavis.servers.notion.description": "Notion — это приложение для совместной продуктивности и ведения заметок", - "tools.klavis.servers.notion.readme": "Подключитесь к Notion для доступа и управления рабочим пространством. Создавайте страницы, ищите контент, обновляйте базы данных и организуйте знания — всё через диалог с ИИ-ассистентом.", - "tools.klavis.servers.onedrive.description": "OneDrive — это сервис хостинга и синхронизации файлов от Microsoft", - "tools.klavis.servers.onedrive.readme": "Интеграция с OneDrive для доступа и управления файлами в облаке Microsoft. Загружайте, скачивайте, делитесь файлами, организуйте папки и сотрудничайте над документами с помощью ИИ.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail — это веб-сервис электронной почты, контактов, задач и календаря от Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Интеграция с Outlook Mail для чтения, отправки и управления электронной почтой Microsoft. Ищите сообщения, создавайте письма, управляйте папками и организуйте почтовый ящик через диалог.", - "tools.klavis.servers.salesforce.description": "Salesforce — ведущая в мире CRM-платформа, помогающая компаниям взаимодействовать с клиентами, партнёрами и потенциальными клиентами", - "tools.klavis.servers.salesforce.readme": "Интеграция с Salesforce для управления клиентскими отношениями и данными о продажах. Выполняйте запросы, обновляйте сделки, отслеживайте лиды и автоматизируйте CRM-процессы с помощью естественного языка.", - "tools.klavis.servers.slack.description": "Slack — это корпоративный мессенджер, соединяющий людей с нужной информацией", - "tools.klavis.servers.slack.readme": "Интеграция со Slack для отправки сообщений, поиска в беседах и управления каналами. Общайтесь с командой, автоматизируйте коммуникации и получайте информацию о рабочем пространстве через диалог.", - "tools.klavis.servers.supabase.description": "Официальный сервер Supabase MCP", - "tools.klavis.servers.supabase.readme": "Интеграция с Supabase для управления базой данных и бэкенд-сервисами. Выполняйте запросы, управляйте аутентификацией, работайте с хранилищем и взаимодействуйте с бэкендом приложения через диалог.", - "tools.klavis.servers.whatsapp.description": "Интеграция с WhatsApp Business API для отправки сообщений, медиа и управления диалогами с клиентами. Идеально подходит для поддержки, маркетинга и автоматизации общения через официальную платформу WhatsApp Business.", - "tools.klavis.servers.whatsapp.readme": "Интеграция с WhatsApp Business для отправки сообщений, управления диалогами и взаимодействия с клиентами. Автоматизируйте коммуникации и обрабатывайте обращения с помощью ИИ.", - "tools.klavis.servers.youtube.description": "YouTube — это платформа для обмена видео, где пользователи могут загружать, делиться и находить контент. Получайте информацию о видео, транскрипты и метаданные программно.", - "tools.klavis.servers.youtube.readme": "Подключитесь к YouTube для поиска видео, доступа к транскриптам и получения информации о роликах. Анализируйте контент, извлекайте метаданные и находите видео через диалог.", - "tools.klavis.servers.zendesk.description": "Zendesk — это компания, разрабатывающая программное обеспечение для поддержки клиентов", - "tools.klavis.servers.zendesk.readme": "Интеграция с Zendesk для управления заявками в поддержку и взаимодействия с клиентами. Создавайте, обновляйте и отслеживайте обращения, получайте доступ к данным клиентов и оптимизируйте поддержку.", - "tools.klavis.tools": "инструменты", - "tools.klavis.verifyAuth": "Я завершил аутентификацию", + "tools.composio.addServer": "Добавить сервер", + "tools.composio.authCompleted": "Аутентификация завершена", + "tools.composio.authFailed": "Ошибка аутентификации", + "tools.composio.authRequired": "Требуется аутентификация", + "tools.composio.connect": "Подключить", + "tools.composio.connected": "Подключено", + "tools.composio.disconnect": "Отключить", + "tools.composio.disconnected": "Отключено", + "tools.composio.error": "Ошибка", + "tools.composio.groupName": "Инструменты Composio", + "tools.composio.manage": "Управление Composio", + "tools.composio.manageTitle": "Управление интеграцией Composio", + "tools.composio.noServers": "Нет подключённых серверов", + "tools.composio.notEnabled": "Служба Composio не включена", + "tools.composio.oauthRequired": "Пожалуйста, завершите OAuth-аутентификацию в новом окне", + "tools.composio.pendingAuth": "Ожидание аутентификации", + "tools.composio.serverCreated": "Сервер успешно создан", + "tools.composio.serverCreatedFailed": "Не удалось создать сервер", + "tools.composio.serverRemoved": "Сервер удалён", + "tools.composio.servers": "серверы", + "tools.composio.servers.airtable.description": "Airtable — это облачная платформа баз данных и электронных таблиц, сочетающая гибкость таблиц с мощью баз данных, позволяя командам организовывать, отслеживать и совместно работать над проектами с настраиваемыми представлениями и мощной автоматизацией.", + "tools.composio.servers.airtable.readme": "Интеграция с Airtable для управления базами данных и рабочими процессами. Выполняйте запросы, создавайте записи, обновляйте данные и автоматизируйте операции с помощью настраиваемых представлений и мощных функций отслеживания.", + "tools.composio.servers.cal-com.description": "Cal.com — это платформа с открытым исходным кодом для планирования встреч без необходимости обмена множеством писем. Управляйте типами событий, бронированиями, доступностью и интеграцией с календарями для удобного планирования.", + "tools.composio.servers.cal-com.readme": "Подключитесь к Cal.com для управления расписанием и встречами. Просматривайте доступность, бронируйте встречи, управляйте типами событий и автоматизируйте календарь с помощью естественного языка.", + "tools.composio.servers.clickup.description": "ClickUp — это универсальная платформа управления проектами и повышения продуктивности, помогающая командам организовывать задачи, управлять проектами и эффективно сотрудничать с помощью настраиваемых рабочих процессов и мощных инструментов отслеживания.", + "tools.composio.servers.clickup.readme": "Интеграция с ClickUp для управления задачами, отслеживания проектов и организации работы. Создавайте задачи, обновляйте статусы, управляйте пользовательскими рабочими процессами и сотрудничайте с командой с помощью команд на естественном языке.", + "tools.composio.servers.confluence.description": "Confluence — это рабочее пространство команды, где сочетаются знания и сотрудничество.", + "tools.composio.servers.confluence.readme": "Интеграция с Confluence для доступа и управления командной документацией. Ищите страницы, создавайте контент, организуйте пространства и развивайте базу знаний с помощью ИИ-ассистента.", + "tools.composio.servers.dropbox.description": "Полноценное решение для управления файлами в облачном хранилище Dropbox. Загружайте, скачивайте, организуйте файлы и папки, управляйте доступом и совместной работой, обрабатывайте версии файлов, создавайте запросы на файлы и выполняйте пакетные операции.", + "tools.composio.servers.dropbox.readme": "Интеграция с Dropbox для доступа и управления файлами. Загружайте, скачивайте, делитесь файлами, управляйте папками, отслеживайте версии и организуйте облачное хранилище с помощью ИИ.", + "tools.composio.servers.figma.description": "Figma — это инструмент совместного проектирования интерфейсов для веб- и мобильных приложений.", + "tools.composio.servers.figma.readme": "Подключитесь к Figma для доступа к дизайн-файлам и совместной работы над проектами. Просматривайте макеты, экспортируйте ресурсы, изучайте компоненты и управляйте рабочим процессом дизайна через естественный диалог.", + "tools.composio.servers.github.description": "Улучшенный сервер GitHub MCP", + "tools.composio.servers.github.readme": "Интеграция с GitHub для управления репозиториями, задачами, pull-запросами и кодом. Ищите код, просматривайте изменения, создавайте ветки и сотрудничайте в разработке программного обеспечения с помощью ИИ.", + "tools.composio.servers.gmail.description": "Gmail — это бесплатный почтовый сервис от Google", + "tools.composio.servers.gmail.readme": "Используйте возможности Gmail прямо в вашем ИИ-ассистенте. Читайте, создавайте и отправляйте письма, ищите в почтовом ящике, управляйте ярлыками и организуйте коммуникации — всё через естественный язык.", + "tools.composio.servers.google-calendar.description": "Google Календарь — это сервис управления временем и расписанием", + "tools.composio.servers.google-calendar.readme": "Интеграция с Google Календарём для просмотра, создания и управления событиями. Планируйте встречи, устанавливайте напоминания, проверяйте доступность и координируйте своё время с помощью команд на естественном языке.", + "tools.composio.servers.google-docs.description": "Google Документы — это текстовый редактор, входящий в бесплатный веб-пакет Google Docs Editors", + "tools.composio.servers.google-docs.readme": "Интеграция с Google Документами для создания, редактирования и управления файлами. Пишите тексты, форматируйте, сотрудничайте в реальном времени и получайте доступ к документам через диалог с ИИ.", + "tools.composio.servers.google-drive.description": "Google Диск — это облачное хранилище", + "tools.composio.servers.google-drive.readme": "Подключитесь к Google Диску для доступа, организации и управления файлами. Ищите документы, загружайте файлы, делитесь контентом и эффективно управляйте облачным хранилищем с помощью ИИ.", + "tools.composio.servers.google-sheets.description": "Google Таблицы — это веб-приложение для создания, редактирования и совместной работы с электронными таблицами", + "tools.composio.servers.google-sheets.readme": "Интеграция с Google Таблицами для чтения, записи и анализа данных. Выполняйте вычисления, создавайте отчёты, строите графики и управляйте табличными данными совместно с ИИ.", + "tools.composio.servers.hubspot.description": "HubSpot — это разработчик программного обеспечения для входящего маркетинга, продаж и обслуживания клиентов", + "tools.composio.servers.hubspot.readme": "Интеграция с HubSpot для управления контактами, сделками и маркетинговыми кампаниями. Получайте доступ к CRM-данным, отслеживайте воронки продаж, автоматизируйте процессы и оптимизируйте маркетинг и продажи.", + "tools.composio.servers.jira.description": "Jira — это инструмент управления проектами и отслеживания задач от Atlassian", + "tools.composio.servers.jira.readme": "Интеграция с Jira для управления задачами, отслеживания прогресса и организации спринтов. Создавайте тикеты, обновляйте статусы, запрашивайте данные проектов и оптимизируйте рабочий процесс разработки через диалог.", + "tools.composio.servers.notion.description": "Notion — это приложение для совместной продуктивности и ведения заметок", + "tools.composio.servers.notion.readme": "Подключитесь к Notion для доступа и управления рабочим пространством. Создавайте страницы, ищите контент, обновляйте базы данных и организуйте знания — всё через диалог с ИИ-ассистентом.", + "tools.composio.servers.onedrive.description": "OneDrive — это сервис хостинга и синхронизации файлов от Microsoft", + "tools.composio.servers.onedrive.readme": "Интеграция с OneDrive для доступа и управления файлами в облаке Microsoft. Загружайте, скачивайте, делитесь файлами, организуйте папки и сотрудничайте над документами с помощью ИИ.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail — это веб-сервис электронной почты, контактов, задач и календаря от Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Интеграция с Outlook Mail для чтения, отправки и управления электронной почтой Microsoft. Ищите сообщения, создавайте письма, управляйте папками и организуйте почтовый ящик через диалог.", + "tools.composio.servers.salesforce.description": "Salesforce — ведущая в мире CRM-платформа, помогающая компаниям взаимодействовать с клиентами, партнёрами и потенциальными клиентами", + "tools.composio.servers.salesforce.readme": "Интеграция с Salesforce для управления клиентскими отношениями и данными о продажах. Выполняйте запросы, обновляйте сделки, отслеживайте лиды и автоматизируйте CRM-процессы с помощью естественного языка.", + "tools.composio.servers.slack.description": "Slack — это корпоративный мессенджер, соединяющий людей с нужной информацией", + "tools.composio.servers.slack.readme": "Интеграция со Slack для отправки сообщений, поиска в беседах и управления каналами. Общайтесь с командой, автоматизируйте коммуникации и получайте информацию о рабочем пространстве через диалог.", + "tools.composio.servers.supabase.description": "Официальный сервер Supabase MCP", + "tools.composio.servers.supabase.readme": "Интеграция с Supabase для управления базой данных и бэкенд-сервисами. Выполняйте запросы, управляйте аутентификацией, работайте с хранилищем и взаимодействуйте с бэкендом приложения через диалог.", + "tools.composio.servers.whatsapp.description": "Интеграция с WhatsApp Business API для отправки сообщений, медиа и управления диалогами с клиентами. Идеально подходит для поддержки, маркетинга и автоматизации общения через официальную платформу WhatsApp Business.", + "tools.composio.servers.whatsapp.readme": "Интеграция с WhatsApp Business для отправки сообщений, управления диалогами и взаимодействия с клиентами. Автоматизируйте коммуникации и обрабатывайте обращения с помощью ИИ.", + "tools.composio.servers.youtube.description": "YouTube — это платформа для обмена видео, где пользователи могут загружать, делиться и находить контент. Получайте информацию о видео, транскрипты и метаданные программно.", + "tools.composio.servers.youtube.readme": "Подключитесь к YouTube для поиска видео, доступа к транскриптам и получения информации о роликах. Анализируйте контент, извлекайте метаданные и находите видео через диалог.", + "tools.composio.servers.zendesk.description": "Zendesk — это компания, разрабатывающая программное обеспечение для поддержки клиентов", + "tools.composio.servers.zendesk.readme": "Интеграция с Zendesk для управления заявками в поддержку и взаимодействия с клиентами. Создавайте, обновляйте и отслеживайте обращения, получайте доступ к данным клиентов и оптимизируйте поддержку.", + "tools.composio.tools": "инструменты", + "tools.composio.verifyAuth": "Я завершил аутентификацию", "tools.lobehubSkill.authorize": "Авторизовать", "tools.lobehubSkill.connect": "Подключить", "tools.lobehubSkill.connected": "Подключено", diff --git a/locales/tr-TR/setting.json b/locales/tr-TR/setting.json index a3572a9ac73..2ff48320561 100644 --- a/locales/tr-TR/setting.json +++ b/locales/tr-TR/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "{{name}} Kaldır", "tools.builtins.uninstalled": "Kaldırıldı", "tools.disabled": "Geçerli model işlev çağrılarını desteklemiyor ve bu yetenek kullanılamaz", - "tools.klavis.addServer": "Sunucu Ekle", - "tools.klavis.authCompleted": "Kimlik Doğrulama Tamamlandı", - "tools.klavis.authFailed": "Kimlik Doğrulama Başarısız", - "tools.klavis.authRequired": "Kimlik Doğrulama Gerekli", - "tools.klavis.connect": "Bağlan", - "tools.klavis.connected": "Bağlandı", - "tools.klavis.disconnect": "Bağlantıyı Kes", - "tools.klavis.disconnected": "Bağlantı Kesildi", - "tools.klavis.error": "Hata", - "tools.klavis.groupName": "Klavis Araçları", - "tools.klavis.manage": "Klavis'i Yönet", - "tools.klavis.manageTitle": "Klavis Entegrasyonunu Yönet", - "tools.klavis.noServers": "Bağlı sunucu yok", - "tools.klavis.notEnabled": "Klavis hizmeti etkin değil", - "tools.klavis.oauthRequired": "Lütfen yeni pencerede OAuth kimlik doğrulamasını tamamlayın", - "tools.klavis.pendingAuth": "Bekleyen Kimlik Doğrulama", - "tools.klavis.remove": "Kaldır", - "tools.klavis.removeConfirm.desc": "{{name}} bağlı hizmetlerinizden kalıcı olarak kaldırılacaktır. Bu işlem geri alınamaz.", - "tools.klavis.removeConfirm.title": "{{name}} kaldırılacak mı?", - "tools.klavis.serverCreated": "Sunucu başarıyla oluşturuldu", - "tools.klavis.serverCreatedFailed": "Sunucu oluşturulamadı", - "tools.klavis.serverRemoved": "Sunucu kaldırıldı", - "tools.klavis.servers": "sunucular", - "tools.klavis.servers.airtable.description": "Airtable, bir elektronik tablo esnekliğini veritabanı gücüyle birleştiren bulut tabanlı bir veritabanı ve tablo platformudur. Takımların projeleri özelleştirilebilir görünümler ve güçlü otomasyon özellikleriyle düzenlemesini, takip etmesini ve iş birliği yapmasını sağlar.", - "tools.klavis.servers.airtable.readme": "Veritabanlarınızı ve iş akışlarınızı yönetmek için Airtable ile entegre olun. Kayıtları sorgulayın, girişler oluşturun, verileri güncelleyin ve özelleştirilebilir görünümlerle işlemleri otomatikleştirin.", - "tools.klavis.servers.cal-com.description": "Cal.com, e-posta trafiği olmadan toplantı planlamanızı sağlayan açık kaynaklı bir zamanlama platformudur. Etkinlik türlerini, rezervasyonları, uygunlukları yönetin ve takvimlerle entegre ederek randevularınızı kolayca planlayın.", - "tools.klavis.servers.cal-com.readme": "Takvim ve randevularınızı yönetmek için Cal.com'a bağlanın. Müsaitlik durumunu görüntüleyin, toplantılar planlayın, etkinlik türlerini yönetin ve takviminizi doğal konuşmalarla otomatikleştirin.", - "tools.klavis.servers.clickup.description": "ClickUp, görevleri düzenlemek, projeleri yönetmek ve özelleştirilebilir iş akışları ile etkili iş birliği sağlamak için kapsamlı bir proje yönetimi ve verimlilik platformudur.", - "tools.klavis.servers.clickup.readme": "Görevleri yönetmek, projeleri takip etmek ve işlerinizi düzenlemek için ClickUp'a bağlanın. Görevler oluşturun, durumları güncelleyin, özel iş akışlarını yönetin ve ekibinizle doğal dil komutlarıyla iş birliği yapın.", - "tools.klavis.servers.confluence.description": "Confluence, bilginin ve iş birliğinin buluştuğu bir ekip çalışma alanıdır.", - "tools.klavis.servers.confluence.readme": "Confluence'a bağlanarak ekip dokümantasyonuna erişin ve yönetin. Sayfaları arayın, içerik oluşturun, alanları düzenleyin ve yapay zeka yardımıyla bilgi tabanınızı oluşturun.", - "tools.klavis.servers.dropbox.description": "Dropbox bulut depolama için eksiksiz bir dosya yönetim çözümüdür. Dosya ve klasörleri yükleyin, indirin, düzenleyin, paylaşımı ve iş birliğini yönetin, dosya sürümlerini kontrol edin, dosya istekleri oluşturun ve toplu işlemler gerçekleştirin.", - "tools.klavis.servers.dropbox.readme": "Dropbox ile entegre olarak dosyalarınıza erişin ve yönetin. Dosya yükleyin, indirin, paylaşın, klasörleri yönetin, dosya sürümlerini kontrol edin ve bulut depolamanızı yapay zeka ile organize edin.", - "tools.klavis.servers.figma.description": "Figma, web ve mobil uygulamalar için iş birliğine dayalı bir arayüz tasarım aracıdır.", - "tools.klavis.servers.figma.readme": "Figma'ya bağlanarak tasarım dosyalarınıza erişin ve projelerde iş birliği yapın. Tasarımları görüntüleyin, varlıkları dışa aktarın, bileşenleri inceleyin ve tasarım iş akışınızı doğal konuşmalarla yönetin.", - "tools.klavis.servers.github.description": "Gelişmiş GitHub MCP Sunucusu", - "tools.klavis.servers.github.readme": "GitHub'a bağlanarak depoları, sorunları, çekme isteklerini ve kodları yönetin. Kod arayın, değişiklikleri inceleyin, dallar oluşturun ve yazılım geliştirme projelerinde yapay zeka ile iş birliği yapın.", - "tools.klavis.servers.gmail.description": "Gmail, Google tarafından sunulan ücretsiz bir e-posta hizmetidir.", - "tools.klavis.servers.gmail.readme": "Gmail’in gücünü doğrudan yapay zeka asistanınıza taşıyın. E-postaları okuyun, yazın ve gönderin, gelen kutunuzu arayın, etiketleri yönetin ve iletişiminizi doğal konuşmalarla düzenleyin.", - "tools.klavis.servers.google-calendar.description": "Google Takvim, zaman yönetimi ve planlama hizmetidir.", - "tools.klavis.servers.google-calendar.readme": "Google Takvim ile entegre olarak etkinliklerinizi sorunsuzca görüntüleyin, oluşturun ve yönetin. Toplantılar planlayın, hatırlatıcılar ayarlayın, müsaitlik durumunu kontrol edin ve zamanınızı doğal dil komutlarıyla koordine edin.", - "tools.klavis.servers.google-docs.description": "Google Dokümanlar, Google Dokümanlar Editörleri paketinin bir parçası olan web tabanlı bir kelime işlemcidir.", - "tools.klavis.servers.google-docs.readme": "Google Dokümanlar ile entegre olarak belgeler oluşturun, düzenleyin ve yönetin. İçerik yazın, metni biçimlendirin, gerçek zamanlı iş birliği yapın ve belgelerinize doğal konuşmalarla erişin.", - "tools.klavis.servers.google-drive.description": "Google Drive, bir bulut depolama hizmetidir.", - "tools.klavis.servers.google-drive.readme": "Google Drive'a bağlanarak dosyalarınıza erişin, düzenleyin ve yönetin. Belgeleri arayın, dosya yükleyin, içerik paylaşın ve bulut depolamanızda yapay zeka yardımıyla gezinin.", - "tools.klavis.servers.google-sheets.description": "Google E-Tablolar, kullanıcıların çevrimiçi olarak e-tablolar oluşturmasına, düzenlemesine ve iş birliği yapmasına olanak tanıyan web tabanlı bir uygulamadır.", - "tools.klavis.servers.google-sheets.readme": "Google E-Tablolar'a bağlanarak tablo verilerini okuyun, yazın ve analiz edin. Hesaplamalar yapın, raporlar oluşturun, grafikler hazırlayın ve yapay zeka yardımıyla verileri iş birliği içinde yönetin.", - "tools.klavis.servers.hubspot.description": "HubSpot, içe dönük pazarlama, satış ve müşteri hizmetleri için yazılım ürünleri geliştiren bir şirkettir.", - "tools.klavis.servers.hubspot.readme": "HubSpot ile entegre olarak kişileri, fırsatları ve pazarlama kampanyalarını yönetin. CRM verilerine erişin, satış süreçlerini takip edin, iş akışlarını otomatikleştirin ve satış-pazarlama operasyonlarınızı kolaylaştırın.", - "tools.klavis.servers.jira.description": "Jira, Atlassian tarafından geliştirilen bir proje yönetimi ve hata takip aracıdır.", - "tools.klavis.servers.jira.readme": "Jira ile entegre olarak sorunları yönetin, ilerlemeyi takip edin ve sprintleri organize edin. Biletler oluşturun, durumları güncelleyin, proje verilerini sorgulayın ve geliştirme iş akışınızı doğal konuşmalarla yönetin.", - "tools.klavis.servers.notion.description": "Notion, iş birliğine dayalı bir üretkenlik ve not alma uygulamasıdır.", - "tools.klavis.servers.notion.readme": "Notion'a bağlanarak çalışma alanınıza erişin ve yönetin. Sayfalar oluşturun, içerik arayın, veritabanlarını güncelleyin ve bilgi tabanınızı yapay zeka destekli doğal konuşmalarla düzenleyin.", - "tools.klavis.servers.onedrive.description": "OneDrive, Microsoft tarafından işletilen bir dosya barındırma ve senkronizasyon hizmetidir.", - "tools.klavis.servers.onedrive.readme": "OneDrive'a bağlanarak Microsoft bulut dosyalarınıza erişin ve yönetin. Dosya yükleyin, indirin, paylaşın, klasörleri düzenleyin ve belgelere yapay zeka yardımıyla iş birliği içinde erişin.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail, Microsoft'un sunduğu web tabanlı e-posta, kişiler, görevler ve takvim hizmetleri paketidir.", - "tools.klavis.servers.outlook-mail.readme": "Outlook Mail ile entegre olarak Microsoft e-postalarınızı okuyun, gönderin ve yönetin. Mesajları arayın, e-postalar yazın, klasörleri yönetin ve gelen kutunuzu doğal konuşmalarla düzenleyin.", - "tools.klavis.servers.salesforce.description": "Salesforce, işletmelerin müşteriler, iş ortakları ve potansiyel müşterilerle bağlantı kurmasına yardımcı olan dünyanın önde gelen müşteri ilişkileri yönetimi (CRM) platformudur.", - "tools.klavis.servers.salesforce.readme": "Salesforce'a bağlanarak müşteri ilişkilerini ve satış verilerini yönetin. Kayıtları sorgulayın, fırsatları güncelleyin, potansiyel müşterileri takip edin ve CRM iş akışlarınızı doğal dil komutlarıyla otomatikleştirin.", - "tools.klavis.servers.slack.description": "Slack, insanların ihtiyaç duyduğu bilgilere ulaşmasını sağlayan bir iş mesajlaşma uygulamasıdır.", - "tools.klavis.servers.slack.readme": "Slack ile entegre olarak mesaj gönderin, konuşmaları arayın ve kanalları yönetin. Ekibinizle bağlantı kurun, iletişim iş akışlarını otomatikleştirin ve çalışma alanı bilgilerine doğal dil ile erişin.", - "tools.klavis.servers.supabase.description": "Supabase resmi MCP Sunucusu", - "tools.klavis.servers.supabase.readme": "Supabase ile entegre olarak veritabanınızı ve arka uç hizmetlerinizi yönetin. Verileri sorgulayın, kimlik doğrulamasını yönetin, depolamayı kontrol edin ve uygulama arka ucunuzla doğal konuşmalarla etkileşim kurun.", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API entegrasyonu, metin mesajları ve medya gönderimi ile müşteri sohbetlerini yönetmenizi sağlar. Müşteri desteği, pazarlama kampanyaları ve otomatik mesajlaşma iş akışları için idealdir.", - "tools.klavis.servers.whatsapp.readme": "WhatsApp Business ile entegre olarak mesaj gönderin, konuşmaları yönetin ve müşterilerle etkileşim kurun. Mesajlaşma iş akışlarını otomatikleştirin ve iletişimi yapay zeka destekli konuşmalarla yönetin.", - "tools.klavis.servers.youtube.description": "YouTube, kullanıcıların video yükleyip paylaşabildiği ve içerik keşfedebildiği bir video paylaşım platformudur. Video bilgilerine, transkriptlere ve meta verilere programlı olarak erişilebilir.", - "tools.klavis.servers.youtube.readme": "YouTube'a bağlanarak videoları arayın, transkriptlere erişin ve video bilgilerini alın. İçeriği analiz edin, meta verileri çıkarın ve videoları doğal konuşmalarla keşfedin.", - "tools.klavis.servers.zendesk.description": "Zendesk, bir müşteri hizmetleri yazılım şirketidir.", - "tools.klavis.servers.zendesk.readme": "Zendesk ile entegre olarak destek taleplerini ve müşteri etkileşimlerini yönetin. Destek istekleri oluşturun, güncelleyin ve takip edin, müşteri verilerine erişin ve destek operasyonlarınızı kolaylaştırın.", - "tools.klavis.tools": "araçlar", - "tools.klavis.verifyAuth": "Kimlik doğrulamasını tamamladım", + "tools.composio.addServer": "Sunucu Ekle", + "tools.composio.authCompleted": "Kimlik Doğrulama Tamamlandı", + "tools.composio.authFailed": "Kimlik Doğrulama Başarısız", + "tools.composio.authRequired": "Kimlik Doğrulama Gerekli", + "tools.composio.connect": "Bağlan", + "tools.composio.connected": "Bağlandı", + "tools.composio.disconnect": "Bağlantıyı Kes", + "tools.composio.disconnected": "Bağlantı Kesildi", + "tools.composio.error": "Hata", + "tools.composio.groupName": "Composio Araçları", + "tools.composio.manage": "Composio'i Yönet", + "tools.composio.manageTitle": "Composio Entegrasyonunu Yönet", + "tools.composio.noServers": "Bağlı sunucu yok", + "tools.composio.notEnabled": "Composio hizmeti etkin değil", + "tools.composio.oauthRequired": "Lütfen yeni pencerede OAuth kimlik doğrulamasını tamamlayın", + "tools.composio.pendingAuth": "Bekleyen Kimlik Doğrulama", + "tools.composio.serverCreated": "Sunucu başarıyla oluşturuldu", + "tools.composio.serverCreatedFailed": "Sunucu oluşturulamadı", + "tools.composio.serverRemoved": "Sunucu kaldırıldı", + "tools.composio.servers": "sunucular", + "tools.composio.servers.airtable.description": "Airtable, bir elektronik tablo esnekliğini veritabanı gücüyle birleştiren bulut tabanlı bir veritabanı ve tablo platformudur. Takımların projeleri özelleştirilebilir görünümler ve güçlü otomasyon özellikleriyle düzenlemesini, takip etmesini ve iş birliği yapmasını sağlar.", + "tools.composio.servers.airtable.readme": "Veritabanlarınızı ve iş akışlarınızı yönetmek için Airtable ile entegre olun. Kayıtları sorgulayın, girişler oluşturun, verileri güncelleyin ve özelleştirilebilir görünümlerle işlemleri otomatikleştirin.", + "tools.composio.servers.cal-com.description": "Cal.com, e-posta trafiği olmadan toplantı planlamanızı sağlayan açık kaynaklı bir zamanlama platformudur. Etkinlik türlerini, rezervasyonları, uygunlukları yönetin ve takvimlerle entegre ederek randevularınızı kolayca planlayın.", + "tools.composio.servers.cal-com.readme": "Takvim ve randevularınızı yönetmek için Cal.com'a bağlanın. Müsaitlik durumunu görüntüleyin, toplantılar planlayın, etkinlik türlerini yönetin ve takviminizi doğal konuşmalarla otomatikleştirin.", + "tools.composio.servers.clickup.description": "ClickUp, görevleri düzenlemek, projeleri yönetmek ve özelleştirilebilir iş akışları ile etkili iş birliği sağlamak için kapsamlı bir proje yönetimi ve verimlilik platformudur.", + "tools.composio.servers.clickup.readme": "Görevleri yönetmek, projeleri takip etmek ve işlerinizi düzenlemek için ClickUp'a bağlanın. Görevler oluşturun, durumları güncelleyin, özel iş akışlarını yönetin ve ekibinizle doğal dil komutlarıyla iş birliği yapın.", + "tools.composio.servers.confluence.description": "Confluence, bilginin ve iş birliğinin buluştuğu bir ekip çalışma alanıdır.", + "tools.composio.servers.confluence.readme": "Confluence'a bağlanarak ekip dokümantasyonuna erişin ve yönetin. Sayfaları arayın, içerik oluşturun, alanları düzenleyin ve yapay zeka yardımıyla bilgi tabanınızı oluşturun.", + "tools.composio.servers.dropbox.description": "Dropbox bulut depolama için eksiksiz bir dosya yönetim çözümüdür. Dosya ve klasörleri yükleyin, indirin, düzenleyin, paylaşımı ve iş birliğini yönetin, dosya sürümlerini kontrol edin, dosya istekleri oluşturun ve toplu işlemler gerçekleştirin.", + "tools.composio.servers.dropbox.readme": "Dropbox ile entegre olarak dosyalarınıza erişin ve yönetin. Dosya yükleyin, indirin, paylaşın, klasörleri yönetin, dosya sürümlerini kontrol edin ve bulut depolamanızı yapay zeka ile organize edin.", + "tools.composio.servers.figma.description": "Figma, web ve mobil uygulamalar için iş birliğine dayalı bir arayüz tasarım aracıdır.", + "tools.composio.servers.figma.readme": "Figma'ya bağlanarak tasarım dosyalarınıza erişin ve projelerde iş birliği yapın. Tasarımları görüntüleyin, varlıkları dışa aktarın, bileşenleri inceleyin ve tasarım iş akışınızı doğal konuşmalarla yönetin.", + "tools.composio.servers.github.description": "Gelişmiş GitHub MCP Sunucusu", + "tools.composio.servers.github.readme": "GitHub'a bağlanarak depoları, sorunları, çekme isteklerini ve kodları yönetin. Kod arayın, değişiklikleri inceleyin, dallar oluşturun ve yazılım geliştirme projelerinde yapay zeka ile iş birliği yapın.", + "tools.composio.servers.gmail.description": "Gmail, Google tarafından sunulan ücretsiz bir e-posta hizmetidir.", + "tools.composio.servers.gmail.readme": "Gmail’in gücünü doğrudan yapay zeka asistanınıza taşıyın. E-postaları okuyun, yazın ve gönderin, gelen kutunuzu arayın, etiketleri yönetin ve iletişiminizi doğal konuşmalarla düzenleyin.", + "tools.composio.servers.google-calendar.description": "Google Takvim, zaman yönetimi ve planlama hizmetidir.", + "tools.composio.servers.google-calendar.readme": "Google Takvim ile entegre olarak etkinliklerinizi sorunsuzca görüntüleyin, oluşturun ve yönetin. Toplantılar planlayın, hatırlatıcılar ayarlayın, müsaitlik durumunu kontrol edin ve zamanınızı doğal dil komutlarıyla koordine edin.", + "tools.composio.servers.google-docs.description": "Google Dokümanlar, Google Dokümanlar Editörleri paketinin bir parçası olan web tabanlı bir kelime işlemcidir.", + "tools.composio.servers.google-docs.readme": "Google Dokümanlar ile entegre olarak belgeler oluşturun, düzenleyin ve yönetin. İçerik yazın, metni biçimlendirin, gerçek zamanlı iş birliği yapın ve belgelerinize doğal konuşmalarla erişin.", + "tools.composio.servers.google-drive.description": "Google Drive, bir bulut depolama hizmetidir.", + "tools.composio.servers.google-drive.readme": "Google Drive'a bağlanarak dosyalarınıza erişin, düzenleyin ve yönetin. Belgeleri arayın, dosya yükleyin, içerik paylaşın ve bulut depolamanızda yapay zeka yardımıyla gezinin.", + "tools.composio.servers.google-sheets.description": "Google E-Tablolar, kullanıcıların çevrimiçi olarak e-tablolar oluşturmasına, düzenlemesine ve iş birliği yapmasına olanak tanıyan web tabanlı bir uygulamadır.", + "tools.composio.servers.google-sheets.readme": "Google E-Tablolar'a bağlanarak tablo verilerini okuyun, yazın ve analiz edin. Hesaplamalar yapın, raporlar oluşturun, grafikler hazırlayın ve yapay zeka yardımıyla verileri iş birliği içinde yönetin.", + "tools.composio.servers.hubspot.description": "HubSpot, içe dönük pazarlama, satış ve müşteri hizmetleri için yazılım ürünleri geliştiren bir şirkettir.", + "tools.composio.servers.hubspot.readme": "HubSpot ile entegre olarak kişileri, fırsatları ve pazarlama kampanyalarını yönetin. CRM verilerine erişin, satış süreçlerini takip edin, iş akışlarını otomatikleştirin ve satış-pazarlama operasyonlarınızı kolaylaştırın.", + "tools.composio.servers.jira.description": "Jira, Atlassian tarafından geliştirilen bir proje yönetimi ve hata takip aracıdır.", + "tools.composio.servers.jira.readme": "Jira ile entegre olarak sorunları yönetin, ilerlemeyi takip edin ve sprintleri organize edin. Biletler oluşturun, durumları güncelleyin, proje verilerini sorgulayın ve geliştirme iş akışınızı doğal konuşmalarla yönetin.", + "tools.composio.servers.notion.description": "Notion, iş birliğine dayalı bir üretkenlik ve not alma uygulamasıdır.", + "tools.composio.servers.notion.readme": "Notion'a bağlanarak çalışma alanınıza erişin ve yönetin. Sayfalar oluşturun, içerik arayın, veritabanlarını güncelleyin ve bilgi tabanınızı yapay zeka destekli doğal konuşmalarla düzenleyin.", + "tools.composio.servers.onedrive.description": "OneDrive, Microsoft tarafından işletilen bir dosya barındırma ve senkronizasyon hizmetidir.", + "tools.composio.servers.onedrive.readme": "OneDrive'a bağlanarak Microsoft bulut dosyalarınıza erişin ve yönetin. Dosya yükleyin, indirin, paylaşın, klasörleri düzenleyin ve belgelere yapay zeka yardımıyla iş birliği içinde erişin.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail, Microsoft'un sunduğu web tabanlı e-posta, kişiler, görevler ve takvim hizmetleri paketidir.", + "tools.composio.servers.outlook-mail.readme": "Outlook Mail ile entegre olarak Microsoft e-postalarınızı okuyun, gönderin ve yönetin. Mesajları arayın, e-postalar yazın, klasörleri yönetin ve gelen kutunuzu doğal konuşmalarla düzenleyin.", + "tools.composio.servers.salesforce.description": "Salesforce, işletmelerin müşteriler, iş ortakları ve potansiyel müşterilerle bağlantı kurmasına yardımcı olan dünyanın önde gelen müşteri ilişkileri yönetimi (CRM) platformudur.", + "tools.composio.servers.salesforce.readme": "Salesforce'a bağlanarak müşteri ilişkilerini ve satış verilerini yönetin. Kayıtları sorgulayın, fırsatları güncelleyin, potansiyel müşterileri takip edin ve CRM iş akışlarınızı doğal dil komutlarıyla otomatikleştirin.", + "tools.composio.servers.slack.description": "Slack, insanların ihtiyaç duyduğu bilgilere ulaşmasını sağlayan bir iş mesajlaşma uygulamasıdır.", + "tools.composio.servers.slack.readme": "Slack ile entegre olarak mesaj gönderin, konuşmaları arayın ve kanalları yönetin. Ekibinizle bağlantı kurun, iletişim iş akışlarını otomatikleştirin ve çalışma alanı bilgilerine doğal dil ile erişin.", + "tools.composio.servers.supabase.description": "Supabase resmi MCP Sunucusu", + "tools.composio.servers.supabase.readme": "Supabase ile entegre olarak veritabanınızı ve arka uç hizmetlerinizi yönetin. Verileri sorgulayın, kimlik doğrulamasını yönetin, depolamayı kontrol edin ve uygulama arka ucunuzla doğal konuşmalarla etkileşim kurun.", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API entegrasyonu, metin mesajları ve medya gönderimi ile müşteri sohbetlerini yönetmenizi sağlar. Müşteri desteği, pazarlama kampanyaları ve otomatik mesajlaşma iş akışları için idealdir.", + "tools.composio.servers.whatsapp.readme": "WhatsApp Business ile entegre olarak mesaj gönderin, konuşmaları yönetin ve müşterilerle etkileşim kurun. Mesajlaşma iş akışlarını otomatikleştirin ve iletişimi yapay zeka destekli konuşmalarla yönetin.", + "tools.composio.servers.youtube.description": "YouTube, kullanıcıların video yükleyip paylaşabildiği ve içerik keşfedebildiği bir video paylaşım platformudur. Video bilgilerine, transkriptlere ve meta verilere programlı olarak erişilebilir.", + "tools.composio.servers.youtube.readme": "YouTube'a bağlanarak videoları arayın, transkriptlere erişin ve video bilgilerini alın. İçeriği analiz edin, meta verileri çıkarın ve videoları doğal konuşmalarla keşfedin.", + "tools.composio.servers.zendesk.description": "Zendesk, bir müşteri hizmetleri yazılım şirketidir.", + "tools.composio.servers.zendesk.readme": "Zendesk ile entegre olarak destek taleplerini ve müşteri etkileşimlerini yönetin. Destek istekleri oluşturun, güncelleyin ve takip edin, müşteri verilerine erişin ve destek operasyonlarınızı kolaylaştırın.", + "tools.composio.tools": "araçlar", + "tools.composio.verifyAuth": "Kimlik doğrulamasını tamamladım", "tools.lobehubSkill.authorize": "Yetkilendir", "tools.lobehubSkill.connect": "Bağlan", "tools.lobehubSkill.connected": "Bağlandı", diff --git a/locales/vi-VN/setting.json b/locales/vi-VN/setting.json index f3eeb108282..2d10c4af39c 100644 --- a/locales/vi-VN/setting.json +++ b/locales/vi-VN/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "Gỡ cài đặt {{name}}", "tools.builtins.uninstalled": "Đã gỡ cài đặt", "tools.disabled": "Mô hình hiện tại không hỗ trợ gọi hàm và không thể sử dụng kỹ năng", - "tools.klavis.addServer": "Thêm Máy Chủ", - "tools.klavis.authCompleted": "Xác Thực Hoàn Tất", - "tools.klavis.authFailed": "Xác Thực Thất Bại", - "tools.klavis.authRequired": "Yêu Cầu Xác Thực", - "tools.klavis.connect": "Kết nối", - "tools.klavis.connected": "Đã Kết Nối", - "tools.klavis.disconnect": "Ngắt kết nối", - "tools.klavis.disconnected": "Mất kết nối", - "tools.klavis.error": "Lỗi", - "tools.klavis.groupName": "Công Cụ Klavis", - "tools.klavis.manage": "Quản Lý Klavis", - "tools.klavis.manageTitle": "Quản Lý Tích Hợp Klavis", - "tools.klavis.noServers": "Không có máy chủ nào được kết nối", - "tools.klavis.notEnabled": "Dịch vụ Klavis chưa được bật", - "tools.klavis.oauthRequired": "Vui lòng hoàn tất xác thực OAuth trong cửa sổ mới", - "tools.klavis.pendingAuth": "Đang Chờ Xác Thực", - "tools.klavis.remove": "Xóa", - "tools.klavis.removeConfirm.desc": "{{name}} sẽ bị xóa vĩnh viễn khỏi các dịch vụ được kết nối của bạn. Hành động này không thể hoàn tác.", - "tools.klavis.removeConfirm.title": "Xóa {{name}}?", - "tools.klavis.serverCreated": "Tạo máy chủ thành công", - "tools.klavis.serverCreatedFailed": "Tạo máy chủ thất bại", - "tools.klavis.serverRemoved": "Đã xóa máy chủ", - "tools.klavis.servers": "máy chủ", - "tools.klavis.servers.airtable.description": "Airtable là nền tảng cơ sở dữ liệu và bảng tính trên đám mây, kết hợp sự linh hoạt của bảng tính với sức mạnh của cơ sở dữ liệu, giúp các nhóm tổ chức, theo dõi và cộng tác trong các dự án với các chế độ xem tùy chỉnh và tính năng tự động hóa mạnh mẽ", - "tools.klavis.servers.airtable.readme": "Tích hợp với Airtable để quản lý cơ sở dữ liệu và quy trình làm việc. Truy vấn bản ghi, tạo mục, cập nhật dữ liệu và tự động hóa thao tác với chế độ xem tùy chỉnh và tính năng theo dõi mạnh mẽ.", - "tools.klavis.servers.cal-com.description": "Cal.com là nền tảng lập lịch mã nguồn mở giúp bạn lên lịch họp mà không cần trao đổi email qua lại. Quản lý loại sự kiện, đặt lịch, thời gian rảnh và tích hợp với lịch để lên lịch hẹn dễ dàng", - "tools.klavis.servers.cal-com.readme": "Kết nối với Cal.com để quản lý lịch trình và cuộc hẹn. Xem thời gian rảnh, đặt lịch họp, quản lý loại sự kiện và tự động hóa lịch của bạn qua hội thoại tự nhiên.", - "tools.klavis.servers.clickup.description": "ClickUp là nền tảng quản lý dự án và năng suất toàn diện giúp các nhóm tổ chức công việc, quản lý dự án và cộng tác hiệu quả với quy trình làm việc tùy chỉnh và tính năng theo dõi mạnh mẽ", - "tools.klavis.servers.clickup.readme": "Kết nối với ClickUp để quản lý công việc, theo dõi dự án và tổ chức công việc của bạn. Tạo nhiệm vụ, cập nhật trạng thái, quản lý quy trình tùy chỉnh và cộng tác với nhóm qua lệnh ngôn ngữ tự nhiên.", - "tools.klavis.servers.confluence.description": "Confluence là không gian làm việc nhóm nơi kiến thức và sự cộng tác hội tụ", - "tools.klavis.servers.confluence.readme": "Kết nối với Confluence để truy cập và quản lý tài liệu nhóm. Tìm kiếm trang, tạo nội dung, tổ chức không gian và xây dựng cơ sở kiến thức của bạn với sự hỗ trợ từ AI hội thoại.", - "tools.klavis.servers.dropbox.description": "Giải pháp quản lý tệp toàn diện cho lưu trữ đám mây Dropbox. Tải lên, tải xuống, tổ chức tệp và thư mục, quản lý chia sẻ và cộng tác, xử lý phiên bản tệp, tạo yêu cầu tệp và thực hiện thao tác hàng loạt trên tệp và thư mục Dropbox của bạn", - "tools.klavis.servers.dropbox.readme": "Tích hợp với Dropbox để truy cập và quản lý tệp của bạn. Tải lên, tải xuống, chia sẻ tệp, quản lý thư mục, xử lý phiên bản tệp và tổ chức lưu trữ đám mây qua AI hội thoại.", - "tools.klavis.servers.figma.description": "Figma là công cụ thiết kế giao diện cộng tác cho ứng dụng web và di động.", - "tools.klavis.servers.figma.readme": "Kết nối với Figma để truy cập tệp thiết kế và cộng tác trong dự án. Xem thiết kế, xuất tài sản, duyệt thành phần và quản lý quy trình thiết kế qua hội thoại tự nhiên.", - "tools.klavis.servers.github.description": "Máy chủ MCP GitHub nâng cao", - "tools.klavis.servers.github.readme": "Kết nối với GitHub để quản lý kho lưu trữ, vấn đề, yêu cầu hợp nhất và mã nguồn. Tìm kiếm mã, xem xét thay đổi, tạo nhánh và cộng tác trong dự án phát triển phần mềm qua AI hội thoại.", - "tools.klavis.servers.gmail.description": "Gmail là dịch vụ email miễn phí do Google cung cấp", - "tools.klavis.servers.gmail.readme": "Mang sức mạnh của Gmail vào trợ lý AI của bạn. Đọc, soạn và gửi email, tìm kiếm hộp thư đến, quản lý nhãn và tổ chức liên lạc—tất cả qua hội thoại tự nhiên.", - "tools.klavis.servers.google-calendar.description": "Google Calendar là dịch vụ lịch và quản lý thời gian", - "tools.klavis.servers.google-calendar.readme": "Tích hợp Google Calendar để xem, tạo và quản lý sự kiện một cách liền mạch. Lên lịch họp, đặt lời nhắc, kiểm tra thời gian rảnh và điều phối thời gian của bạn—tất cả qua lệnh ngôn ngữ tự nhiên.", - "tools.klavis.servers.google-docs.description": "Google Docs là trình xử lý văn bản nằm trong bộ công cụ Google Docs Editors miễn phí trên nền web", - "tools.klavis.servers.google-docs.readme": "Tích hợp với Google Docs để tạo, chỉnh sửa và quản lý tài liệu. Soạn nội dung, định dạng văn bản, cộng tác theo thời gian thực và truy cập tài liệu qua hội thoại tự nhiên.", - "tools.klavis.servers.google-drive.description": "Google Drive là dịch vụ lưu trữ đám mây", - "tools.klavis.servers.google-drive.readme": "Kết nối với Google Drive để truy cập, tổ chức và quản lý tệp của bạn. Tìm kiếm tài liệu, tải lên tệp, chia sẻ nội dung và điều hướng lưu trữ đám mây hiệu quả với sự hỗ trợ từ AI.", - "tools.klavis.servers.google-sheets.description": "Google Sheets là ứng dụng bảng tính trên nền web cho phép người dùng tạo, chỉnh sửa và cộng tác trên bảng tính trực tuyến", - "tools.klavis.servers.google-sheets.readme": "Kết nối với Google Sheets để đọc, ghi và phân tích dữ liệu bảng tính. Thực hiện tính toán, tạo báo cáo, vẽ biểu đồ và quản lý dữ liệu dạng bảng cùng AI hỗ trợ.", - "tools.klavis.servers.hubspot.description": "HubSpot là nhà phát triển và tiếp thị phần mềm cho marketing, bán hàng và dịch vụ khách hàng theo phương pháp inbound", - "tools.klavis.servers.hubspot.readme": "Tích hợp với HubSpot để quản lý liên hệ, giao dịch và chiến dịch tiếp thị. Truy cập dữ liệu CRM, theo dõi quy trình bán hàng, tự động hóa quy trình và tối ưu hóa hoạt động tiếp thị của bạn.", - "tools.klavis.servers.jira.description": "Jira là công cụ quản lý dự án và theo dõi lỗi do Atlassian phát triển", - "tools.klavis.servers.jira.readme": "Tích hợp với Jira để quản lý vấn đề, theo dõi tiến độ và tổ chức sprint. Tạo ticket, cập nhật trạng thái, truy vấn dữ liệu dự án và tối ưu hóa quy trình phát triển qua hội thoại tự nhiên.", - "tools.klavis.servers.notion.description": "Notion là ứng dụng ghi chú và năng suất cộng tác", - "tools.klavis.servers.notion.readme": "Kết nối với Notion để truy cập và quản lý không gian làm việc của bạn. Tạo trang, tìm kiếm nội dung, cập nhật cơ sở dữ liệu và tổ chức kiến thức—tất cả qua hội thoại tự nhiên với trợ lý AI.", - "tools.klavis.servers.onedrive.description": "OneDrive là dịch vụ lưu trữ và đồng bộ hóa tệp do Microsoft vận hành", - "tools.klavis.servers.onedrive.readme": "Kết nối với OneDrive để truy cập và quản lý tệp đám mây Microsoft của bạn. Tải lên, tải xuống, chia sẻ tệp, tổ chức thư mục và cộng tác trên tài liệu với sự hỗ trợ từ AI.", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail là bộ dịch vụ webmail, danh bạ, nhiệm vụ và lịch trên nền web của Microsoft.", - "tools.klavis.servers.outlook-mail.readme": "Tích hợp với Outlook Mail để đọc, gửi và quản lý email Microsoft của bạn. Tìm kiếm thư, soạn email, quản lý thư mục và tổ chức hộp thư đến qua hội thoại tự nhiên.", - "tools.klavis.servers.salesforce.description": "Salesforce là nền tảng quản lý quan hệ khách hàng (CRM) hàng đầu thế giới giúp doanh nghiệp kết nối với khách hàng, đối tác và khách hàng tiềm năng", - "tools.klavis.servers.salesforce.readme": "Kết nối với Salesforce để quản lý mối quan hệ khách hàng và dữ liệu bán hàng. Truy vấn bản ghi, cập nhật cơ hội, theo dõi khách hàng tiềm năng và tự động hóa quy trình CRM qua lệnh ngôn ngữ tự nhiên.", - "tools.klavis.servers.slack.description": "Slack là ứng dụng nhắn tin cho doanh nghiệp giúp kết nối mọi người với thông tin họ cần", - "tools.klavis.servers.slack.readme": "Tích hợp với Slack để gửi tin nhắn, tìm kiếm hội thoại và quản lý kênh. Kết nối với nhóm của bạn, tự động hóa quy trình giao tiếp và truy cập thông tin không gian làm việc qua ngôn ngữ tự nhiên.", - "tools.klavis.servers.supabase.description": "Máy chủ MCP chính thức của Supabase", - "tools.klavis.servers.supabase.readme": "Tích hợp với Supabase để quản lý cơ sở dữ liệu và dịch vụ backend. Truy vấn dữ liệu, quản lý xác thực, xử lý lưu trữ và tương tác với backend ứng dụng qua hội thoại tự nhiên.", - "tools.klavis.servers.whatsapp.description": "Tích hợp API WhatsApp Business cho phép gửi tin nhắn văn bản, phương tiện và quản lý cuộc trò chuyện với khách hàng. Phù hợp cho hỗ trợ khách hàng, chiến dịch marketing và quy trình nhắn tin tự động qua nền tảng WhatsApp Business chính thức.", - "tools.klavis.servers.whatsapp.readme": "Tích hợp với WhatsApp Business để gửi tin nhắn, quản lý hội thoại và tương tác với khách hàng. Tự động hóa quy trình nhắn tin và xử lý liên lạc qua AI hội thoại.", - "tools.klavis.servers.youtube.description": "YouTube là nền tảng chia sẻ video nơi người dùng có thể tải lên, chia sẻ và khám phá nội dung. Truy cập thông tin video, bản ghi và siêu dữ liệu qua lập trình.", - "tools.klavis.servers.youtube.readme": "Kết nối với YouTube để tìm kiếm video, truy cập bản ghi và lấy thông tin video. Phân tích nội dung, trích xuất siêu dữ liệu và khám phá video qua hội thoại tự nhiên.", - "tools.klavis.servers.zendesk.description": "Zendesk là công ty phần mềm dịch vụ khách hàng", - "tools.klavis.servers.zendesk.readme": "Tích hợp với Zendesk để quản lý phiếu hỗ trợ và tương tác khách hàng. Tạo, cập nhật và theo dõi yêu cầu hỗ trợ, truy cập dữ liệu khách hàng và tối ưu hóa hoạt động hỗ trợ.", - "tools.klavis.tools": "công cụ", - "tools.klavis.verifyAuth": "Tôi đã hoàn tất xác thực", + "tools.composio.addServer": "Thêm Máy Chủ", + "tools.composio.authCompleted": "Xác Thực Hoàn Tất", + "tools.composio.authFailed": "Xác Thực Thất Bại", + "tools.composio.authRequired": "Yêu Cầu Xác Thực", + "tools.composio.connect": "Kết nối", + "tools.composio.connected": "Đã Kết Nối", + "tools.composio.disconnect": "Ngắt kết nối", + "tools.composio.disconnected": "Mất kết nối", + "tools.composio.error": "Lỗi", + "tools.composio.groupName": "Công Cụ Composio", + "tools.composio.manage": "Quản Lý Composio", + "tools.composio.manageTitle": "Quản Lý Tích Hợp Composio", + "tools.composio.noServers": "Không có máy chủ nào được kết nối", + "tools.composio.notEnabled": "Dịch vụ Composio chưa được bật", + "tools.composio.oauthRequired": "Vui lòng hoàn tất xác thực OAuth trong cửa sổ mới", + "tools.composio.pendingAuth": "Đang Chờ Xác Thực", + "tools.composio.serverCreated": "Tạo máy chủ thành công", + "tools.composio.serverCreatedFailed": "Tạo máy chủ thất bại", + "tools.composio.serverRemoved": "Đã xóa máy chủ", + "tools.composio.servers": "máy chủ", + "tools.composio.servers.airtable.description": "Airtable là nền tảng cơ sở dữ liệu và bảng tính trên đám mây, kết hợp sự linh hoạt của bảng tính với sức mạnh của cơ sở dữ liệu, giúp các nhóm tổ chức, theo dõi và cộng tác trong các dự án với các chế độ xem tùy chỉnh và tính năng tự động hóa mạnh mẽ", + "tools.composio.servers.airtable.readme": "Tích hợp với Airtable để quản lý cơ sở dữ liệu và quy trình làm việc. Truy vấn bản ghi, tạo mục, cập nhật dữ liệu và tự động hóa thao tác với chế độ xem tùy chỉnh và tính năng theo dõi mạnh mẽ.", + "tools.composio.servers.cal-com.description": "Cal.com là nền tảng lập lịch mã nguồn mở giúp bạn lên lịch họp mà không cần trao đổi email qua lại. Quản lý loại sự kiện, đặt lịch, thời gian rảnh và tích hợp với lịch để lên lịch hẹn dễ dàng", + "tools.composio.servers.cal-com.readme": "Kết nối với Cal.com để quản lý lịch trình và cuộc hẹn. Xem thời gian rảnh, đặt lịch họp, quản lý loại sự kiện và tự động hóa lịch của bạn qua hội thoại tự nhiên.", + "tools.composio.servers.clickup.description": "ClickUp là nền tảng quản lý dự án và năng suất toàn diện giúp các nhóm tổ chức công việc, quản lý dự án và cộng tác hiệu quả với quy trình làm việc tùy chỉnh và tính năng theo dõi mạnh mẽ", + "tools.composio.servers.clickup.readme": "Kết nối với ClickUp để quản lý công việc, theo dõi dự án và tổ chức công việc của bạn. Tạo nhiệm vụ, cập nhật trạng thái, quản lý quy trình tùy chỉnh và cộng tác với nhóm qua lệnh ngôn ngữ tự nhiên.", + "tools.composio.servers.confluence.description": "Confluence là không gian làm việc nhóm nơi kiến thức và sự cộng tác hội tụ", + "tools.composio.servers.confluence.readme": "Kết nối với Confluence để truy cập và quản lý tài liệu nhóm. Tìm kiếm trang, tạo nội dung, tổ chức không gian và xây dựng cơ sở kiến thức của bạn với sự hỗ trợ từ AI hội thoại.", + "tools.composio.servers.dropbox.description": "Giải pháp quản lý tệp toàn diện cho lưu trữ đám mây Dropbox. Tải lên, tải xuống, tổ chức tệp và thư mục, quản lý chia sẻ và cộng tác, xử lý phiên bản tệp, tạo yêu cầu tệp và thực hiện thao tác hàng loạt trên tệp và thư mục Dropbox của bạn", + "tools.composio.servers.dropbox.readme": "Tích hợp với Dropbox để truy cập và quản lý tệp của bạn. Tải lên, tải xuống, chia sẻ tệp, quản lý thư mục, xử lý phiên bản tệp và tổ chức lưu trữ đám mây qua AI hội thoại.", + "tools.composio.servers.figma.description": "Figma là công cụ thiết kế giao diện cộng tác cho ứng dụng web và di động.", + "tools.composio.servers.figma.readme": "Kết nối với Figma để truy cập tệp thiết kế và cộng tác trong dự án. Xem thiết kế, xuất tài sản, duyệt thành phần và quản lý quy trình thiết kế qua hội thoại tự nhiên.", + "tools.composio.servers.github.description": "Máy chủ MCP GitHub nâng cao", + "tools.composio.servers.github.readme": "Kết nối với GitHub để quản lý kho lưu trữ, vấn đề, yêu cầu hợp nhất và mã nguồn. Tìm kiếm mã, xem xét thay đổi, tạo nhánh và cộng tác trong dự án phát triển phần mềm qua AI hội thoại.", + "tools.composio.servers.gmail.description": "Gmail là dịch vụ email miễn phí do Google cung cấp", + "tools.composio.servers.gmail.readme": "Mang sức mạnh của Gmail vào trợ lý AI của bạn. Đọc, soạn và gửi email, tìm kiếm hộp thư đến, quản lý nhãn và tổ chức liên lạc—tất cả qua hội thoại tự nhiên.", + "tools.composio.servers.google-calendar.description": "Google Calendar là dịch vụ lịch và quản lý thời gian", + "tools.composio.servers.google-calendar.readme": "Tích hợp Google Calendar để xem, tạo và quản lý sự kiện một cách liền mạch. Lên lịch họp, đặt lời nhắc, kiểm tra thời gian rảnh và điều phối thời gian của bạn—tất cả qua lệnh ngôn ngữ tự nhiên.", + "tools.composio.servers.google-docs.description": "Google Docs là trình xử lý văn bản nằm trong bộ công cụ Google Docs Editors miễn phí trên nền web", + "tools.composio.servers.google-docs.readme": "Tích hợp với Google Docs để tạo, chỉnh sửa và quản lý tài liệu. Soạn nội dung, định dạng văn bản, cộng tác theo thời gian thực và truy cập tài liệu qua hội thoại tự nhiên.", + "tools.composio.servers.google-drive.description": "Google Drive là dịch vụ lưu trữ đám mây", + "tools.composio.servers.google-drive.readme": "Kết nối với Google Drive để truy cập, tổ chức và quản lý tệp của bạn. Tìm kiếm tài liệu, tải lên tệp, chia sẻ nội dung và điều hướng lưu trữ đám mây hiệu quả với sự hỗ trợ từ AI.", + "tools.composio.servers.google-sheets.description": "Google Sheets là ứng dụng bảng tính trên nền web cho phép người dùng tạo, chỉnh sửa và cộng tác trên bảng tính trực tuyến", + "tools.composio.servers.google-sheets.readme": "Kết nối với Google Sheets để đọc, ghi và phân tích dữ liệu bảng tính. Thực hiện tính toán, tạo báo cáo, vẽ biểu đồ và quản lý dữ liệu dạng bảng cùng AI hỗ trợ.", + "tools.composio.servers.hubspot.description": "HubSpot là nhà phát triển và tiếp thị phần mềm cho marketing, bán hàng và dịch vụ khách hàng theo phương pháp inbound", + "tools.composio.servers.hubspot.readme": "Tích hợp với HubSpot để quản lý liên hệ, giao dịch và chiến dịch tiếp thị. Truy cập dữ liệu CRM, theo dõi quy trình bán hàng, tự động hóa quy trình và tối ưu hóa hoạt động tiếp thị của bạn.", + "tools.composio.servers.jira.description": "Jira là công cụ quản lý dự án và theo dõi lỗi do Atlassian phát triển", + "tools.composio.servers.jira.readme": "Tích hợp với Jira để quản lý vấn đề, theo dõi tiến độ và tổ chức sprint. Tạo ticket, cập nhật trạng thái, truy vấn dữ liệu dự án và tối ưu hóa quy trình phát triển qua hội thoại tự nhiên.", + "tools.composio.servers.notion.description": "Notion là ứng dụng ghi chú và năng suất cộng tác", + "tools.composio.servers.notion.readme": "Kết nối với Notion để truy cập và quản lý không gian làm việc của bạn. Tạo trang, tìm kiếm nội dung, cập nhật cơ sở dữ liệu và tổ chức kiến thức—tất cả qua hội thoại tự nhiên với trợ lý AI.", + "tools.composio.servers.onedrive.description": "OneDrive là dịch vụ lưu trữ và đồng bộ hóa tệp do Microsoft vận hành", + "tools.composio.servers.onedrive.readme": "Kết nối với OneDrive để truy cập và quản lý tệp đám mây Microsoft của bạn. Tải lên, tải xuống, chia sẻ tệp, tổ chức thư mục và cộng tác trên tài liệu với sự hỗ trợ từ AI.", + "tools.composio.servers.outlook-mail.description": "Outlook Mail là bộ dịch vụ webmail, danh bạ, nhiệm vụ và lịch trên nền web của Microsoft.", + "tools.composio.servers.outlook-mail.readme": "Tích hợp với Outlook Mail để đọc, gửi và quản lý email Microsoft của bạn. Tìm kiếm thư, soạn email, quản lý thư mục và tổ chức hộp thư đến qua hội thoại tự nhiên.", + "tools.composio.servers.salesforce.description": "Salesforce là nền tảng quản lý quan hệ khách hàng (CRM) hàng đầu thế giới giúp doanh nghiệp kết nối với khách hàng, đối tác và khách hàng tiềm năng", + "tools.composio.servers.salesforce.readme": "Kết nối với Salesforce để quản lý mối quan hệ khách hàng và dữ liệu bán hàng. Truy vấn bản ghi, cập nhật cơ hội, theo dõi khách hàng tiềm năng và tự động hóa quy trình CRM qua lệnh ngôn ngữ tự nhiên.", + "tools.composio.servers.slack.description": "Slack là ứng dụng nhắn tin cho doanh nghiệp giúp kết nối mọi người với thông tin họ cần", + "tools.composio.servers.slack.readme": "Tích hợp với Slack để gửi tin nhắn, tìm kiếm hội thoại và quản lý kênh. Kết nối với nhóm của bạn, tự động hóa quy trình giao tiếp và truy cập thông tin không gian làm việc qua ngôn ngữ tự nhiên.", + "tools.composio.servers.supabase.description": "Máy chủ MCP chính thức của Supabase", + "tools.composio.servers.supabase.readme": "Tích hợp với Supabase để quản lý cơ sở dữ liệu và dịch vụ backend. Truy vấn dữ liệu, quản lý xác thực, xử lý lưu trữ và tương tác với backend ứng dụng qua hội thoại tự nhiên.", + "tools.composio.servers.whatsapp.description": "Tích hợp API WhatsApp Business cho phép gửi tin nhắn văn bản, phương tiện và quản lý cuộc trò chuyện với khách hàng. Phù hợp cho hỗ trợ khách hàng, chiến dịch marketing và quy trình nhắn tin tự động qua nền tảng WhatsApp Business chính thức.", + "tools.composio.servers.whatsapp.readme": "Tích hợp với WhatsApp Business để gửi tin nhắn, quản lý hội thoại và tương tác với khách hàng. Tự động hóa quy trình nhắn tin và xử lý liên lạc qua AI hội thoại.", + "tools.composio.servers.youtube.description": "YouTube là nền tảng chia sẻ video nơi người dùng có thể tải lên, chia sẻ và khám phá nội dung. Truy cập thông tin video, bản ghi và siêu dữ liệu qua lập trình.", + "tools.composio.servers.youtube.readme": "Kết nối với YouTube để tìm kiếm video, truy cập bản ghi và lấy thông tin video. Phân tích nội dung, trích xuất siêu dữ liệu và khám phá video qua hội thoại tự nhiên.", + "tools.composio.servers.zendesk.description": "Zendesk là công ty phần mềm dịch vụ khách hàng", + "tools.composio.servers.zendesk.readme": "Tích hợp với Zendesk để quản lý phiếu hỗ trợ và tương tác khách hàng. Tạo, cập nhật và theo dõi yêu cầu hỗ trợ, truy cập dữ liệu khách hàng và tối ưu hóa hoạt động hỗ trợ.", + "tools.composio.tools": "công cụ", + "tools.composio.verifyAuth": "Tôi đã hoàn tất xác thực", "tools.lobehubSkill.authorize": "Ủy quyền", "tools.lobehubSkill.connect": "Kết nối", "tools.lobehubSkill.connected": "Đã kết nối", diff --git a/locales/zh-CN/setting.json b/locales/zh-CN/setting.json index b01a7cb3c55..c2a40317339 100644 --- a/locales/zh-CN/setting.json +++ b/locales/zh-CN/setting.json @@ -1172,77 +1172,78 @@ "tools.builtins.uninstallConfirm.title": "卸载 {{name}}", "tools.builtins.uninstalled": "已卸载", "tools.disabled": "当前模型不支持函数调用,无法使用技能", - "tools.klavis.addServer": "添加服务器", - "tools.klavis.authCompleted": "认证完成", - "tools.klavis.authFailed": "认证失败", - "tools.klavis.authRequired": "需要认证", - "tools.klavis.connect": "连接", - "tools.klavis.connected": "已连接", - "tools.klavis.disconnect": "断开连接", - "tools.klavis.disconnected": "已断开连接", - "tools.klavis.error": "错误", - "tools.klavis.groupName": "Klavis 工具", - "tools.klavis.manage": "管理 Klavis", - "tools.klavis.manageTitle": "管理 Klavis 集成", - "tools.klavis.noServers": "暂无连接的服务器", - "tools.klavis.notEnabled": "Klavis 服务未启用", - "tools.klavis.oauthRequired": "请在新窗口中完成 OAuth 认证", - "tools.klavis.pendingAuth": "待认证", - "tools.klavis.remove": "移除", - "tools.klavis.removeConfirm.desc": "{{name}} 将从您的已连接服务中永久移除,此操作不可撤销。", - "tools.klavis.removeConfirm.title": "移除 {{name}}?", - "tools.klavis.serverCreated": "服务器创建成功", - "tools.klavis.serverCreatedFailed": "服务器创建失败", - "tools.klavis.serverRemoved": "服务器已删除", - "tools.klavis.servers": "个服务器", - "tools.klavis.servers.airtable.description": "Airtable 是一款基于云的数据库和电子表格平台,结合了电子表格的灵活性与数据库的强大功能,使团队能够通过可自定义视图和强大的自动化功能来组织、跟踪和协作项目。", - "tools.klavis.servers.airtable.readme": "集成 Airtable 以管理数据库和工作流程。查询记录、创建条目、更新数据,并通过可自定义视图和强大的跟踪功能实现自动化操作。", - "tools.klavis.servers.cal-com.description": "Cal.com 是一个开源的日程安排平台,帮助您无需反复邮件即可安排会议。管理事件类型、预订、可用时间,并与日历集成,实现无缝预约安排。", - "tools.klavis.servers.cal-com.readme": "连接 Cal.com 以管理您的日程和预约。查看可用时间、预订会议、管理事件类型,并通过自然对话自动化您的日历。", - "tools.klavis.servers.clickup.description": "ClickUp 是一个全面的项目管理和效率平台,帮助团队组织任务、管理项目,并通过可自定义的工作流程和强大的跟踪功能高效协作。", - "tools.klavis.servers.clickup.readme": "连接 ClickUp 以管理任务、跟踪项目并组织工作。创建任务、更新状态、管理自定义工作流程,并通过自然语言指令与团队协作。", - "tools.klavis.servers.confluence.description": "Confluence 是一个团队协作空间,融合了知识管理与协作功能。", - "tools.klavis.servers.confluence.readme": "连接 Confluence 以访问和管理团队文档。搜索页面、创建内容、组织空间,并通过对话式 AI 构建您的知识库。", - "tools.klavis.servers.dropbox.description": "Dropbox 云存储的完整文件管理解决方案。上传、下载、组织文件和文件夹,管理共享与协作,处理文件版本,创建文件请求,并对文件和文件夹执行批量操作。", - "tools.klavis.servers.dropbox.readme": "集成 Dropbox 以访问和管理您的文件。上传、下载、共享文件,管理文件夹,处理文件版本,并通过对话式 AI 组织您的云存储。", - "tools.klavis.servers.figma.description": "Figma 是一款用于网页和移动应用界面的协作设计工具。", - "tools.klavis.servers.figma.readme": "连接 Figma 以访问设计文件并协作项目。查看设计、导出资源、浏览组件,并通过自然对话管理设计流程。", - "tools.klavis.servers.github.description": "增强版 GitHub MCP 服务器", - "tools.klavis.servers.github.readme": "连接 GitHub 以管理代码库、问题、拉取请求和代码。搜索代码、审查更改、创建分支,并通过对话式 AI 协作开发项目。", - "tools.klavis.servers.gmail.description": "Gmail 是 Google 提供的免费电子邮件服务", - "tools.klavis.servers.gmail.readme": "将 Gmail 的强大功能直接引入您的 AI 助手。阅读、撰写和发送邮件,搜索收件箱,管理标签,并通过自然对话组织您的通信。", - "tools.klavis.servers.google-calendar.description": "Google 日历是一项时间管理和日程安排服务", - "tools.klavis.servers.google-calendar.readme": "集成 Google 日历以无缝查看、创建和管理事件。安排会议、设置提醒、查看可用时间,并通过自然语言指令协调您的时间。", - "tools.klavis.servers.google-docs.description": "Google 文档是 Google 提供的免费网页文字处理工具,属于 Google 文档编辑器套件的一部分", - "tools.klavis.servers.google-docs.readme": "集成 Google 文档以创建、编辑和管理文档。撰写内容、格式化文本、实时协作,并通过自然对话访问您的文档。", - "tools.klavis.servers.google-drive.description": "Google 云端硬盘是一项云存储服务", - "tools.klavis.servers.google-drive.readme": "连接 Google 云端硬盘以访问、组织和管理您的文件。搜索文档、上传文件、共享内容,并通过 AI 助手高效导航您的云存储。", - "tools.klavis.servers.google-sheets.description": "Google 表格是一款基于网页的电子表格应用,允许用户在线创建、编辑和协作处理表格", - "tools.klavis.servers.google-sheets.readme": "连接 Google 表格以读取、编写和分析表格数据。执行计算、生成报告、创建图表,并通过 AI 协作管理表格数据。", - "tools.klavis.servers.hubspot.description": "HubSpot 是一家专注于入站营销、销售和客户服务的软件开发商", - "tools.klavis.servers.hubspot.readme": "集成 HubSpot 以管理联系人、交易和营销活动。访问 CRM 数据、跟踪销售流程、自动化工作流,并优化销售与营销操作。", - "tools.klavis.servers.jira.description": "Jira 是由 Atlassian 开发的项目管理和问题跟踪工具", - "tools.klavis.servers.jira.readme": "集成 Jira 以管理问题、跟踪进度并组织冲刺。创建工单、更新状态、查询项目数据,并通过自然对话优化开发流程。", - "tools.klavis.servers.notion.description": "Notion 是一款协作型效率与笔记应用", - "tools.klavis.servers.notion.readme": "连接 Notion 以访问和管理您的工作区。创建页面、搜索内容、更新数据库,并通过与 AI 助手的自然对话组织知识库。", - "tools.klavis.servers.onedrive.description": "OneDrive 是由微软运营的文件托管和同步服务", - "tools.klavis.servers.onedrive.readme": "连接 OneDrive 以访问和管理您的微软云文件。上传、下载、共享文件,组织文件夹,并通过 AI 助手协作处理文档。", - "tools.klavis.servers.outlook-mail.description": "Outlook 邮件是微软提供的基于网页的邮件、联系人、任务和日历服务套件。", - "tools.klavis.servers.outlook-mail.readme": "集成 Outlook 邮件以阅读、发送和管理您的微软邮件。搜索消息、撰写邮件、管理文件夹,并通过自然对话整理收件箱。", - "tools.klavis.servers.salesforce.description": "Salesforce 是全球领先的客户关系管理(CRM)平台,帮助企业与客户、合作伙伴和潜在客户建立联系", - "tools.klavis.servers.salesforce.readme": "连接 Salesforce 以管理客户关系和销售数据。查询记录、更新商机、跟踪潜在客户,并通过自然语言指令自动化 CRM 工作流。", - "tools.klavis.servers.slack.description": "Slack 是一款为企业设计的消息应用,帮助人们获取所需信息", - "tools.klavis.servers.slack.readme": "集成 Slack 以发送消息、搜索对话并管理频道。与团队连接、自动化沟通流程,并通过自然语言访问工作区信息。", - "tools.klavis.servers.supabase.description": "Supabase 官方 MCP 服务器", - "tools.klavis.servers.supabase.readme": "集成 Supabase 以管理数据库和后端服务。查询数据、管理身份验证、处理存储,并通过自然对话与应用后端交互。", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API 集成,支持发送文本、媒体并管理客户对话。适用于客户支持、营销活动和通过官方 WhatsApp Business 平台实现的自动化消息工作流。", - "tools.klavis.servers.whatsapp.readme": "集成 WhatsApp Business 以发送消息、管理对话并与客户互动。通过对话式 AI 自动化消息流程并处理通信。", - "tools.klavis.servers.youtube.description": "YouTube 是一个视频分享平台,用户可以上传、分享和发现内容。可编程访问视频信息、字幕和元数据。", - "tools.klavis.servers.youtube.readme": "连接 YouTube 以搜索视频、访问字幕并获取视频信息。分析内容、提取元数据,并通过自然对话发现视频。", - "tools.klavis.servers.zendesk.description": "Zendesk 是一家客户服务软件公司", - "tools.klavis.servers.zendesk.readme": "集成 Zendesk 以管理支持工单和客户互动。创建、更新和跟踪支持请求,访问客户数据,并优化您的客服流程。", - "tools.klavis.tools": "个工具", - "tools.klavis.verifyAuth": "我已完成认证", + "tools.composio.addServer": "添加服务器", + "tools.composio.authCompleted": "认证完成", + "tools.composio.authFailed": "认证失败", + "tools.composio.authRequired": "需要认证", + "tools.composio.connect": "连接", + "tools.composio.connected": "已连接", + "tools.composio.disconnect": "断开连接", + "tools.composio.disconnected": "已断开连接", + "tools.composio.error": "错误", + "tools.composio.remove": "移除", + "tools.composio.removeConfirm.desc": "{{name}} 将从您的已连接服务中永久移除,此操作不可撤销。", + "tools.composio.removeConfirm.title": "移除 {{name}}?", + "tools.composio.groupName": "Composio 工具", + "tools.composio.manage": "管理 Composio", + "tools.composio.manageTitle": "管理 Composio 集成", + "tools.composio.noServers": "暂无连接的服务器", + "tools.composio.notEnabled": "Composio 服务未启用", + "tools.composio.oauthRequired": "请在新窗口中完成 OAuth 认证", + "tools.composio.pendingAuth": "待认证", + "tools.composio.reauthorize": "重新授权", + "tools.composio.serverCreated": "服务器创建成功", + "tools.composio.serverCreatedFailed": "服务器创建失败", + "tools.composio.serverRemoved": "服务器已删除", + "tools.composio.servers": "个服务器", + "tools.composio.servers.airtable.description": "Airtable 是一款基于云的数据库和电子表格平台,结合了电子表格的灵活性与数据库的强大功能,使团队能够通过可自定义视图和强大的自动化功能来组织、跟踪和协作项目。", + "tools.composio.servers.airtable.readme": "集成 Airtable 以管理数据库和工作流程。查询记录、创建条目、更新数据,并通过可自定义视图和强大的跟踪功能实现自动化操作。", + "tools.composio.servers.cal-com.description": "Cal.com 是一个开源的日程安排平台,帮助您无需反复邮件即可安排会议。管理事件类型、预订、可用时间,并与日历集成,实现无缝预约安排。", + "tools.composio.servers.cal-com.readme": "连接 Cal.com 以管理您的日程和预约。查看可用时间、预订会议、管理事件类型,并通过自然对话自动化您的日历。", + "tools.composio.servers.clickup.description": "ClickUp 是一个全面的项目管理和效率平台,帮助团队组织任务、管理项目,并通过可自定义的工作流程和强大的跟踪功能高效协作。", + "tools.composio.servers.clickup.readme": "连接 ClickUp 以管理任务、跟踪项目并组织工作。创建任务、更新状态、管理自定义工作流程,并通过自然语言指令与团队协作。", + "tools.composio.servers.confluence.description": "Confluence 是一个团队协作空间,融合了知识管理与协作功能。", + "tools.composio.servers.confluence.readme": "连接 Confluence 以访问和管理团队文档。搜索页面、创建内容、组织空间,并通过对话式 AI 构建您的知识库。", + "tools.composio.servers.dropbox.description": "Dropbox 云存储的完整文件管理解决方案。上传、下载、组织文件和文件夹,管理共享与协作,处理文件版本,创建文件请求,并对文件和文件夹执行批量操作。", + "tools.composio.servers.dropbox.readme": "集成 Dropbox 以访问和管理您的文件。上传、下载、共享文件,管理文件夹,处理文件版本,并通过对话式 AI 组织您的云存储。", + "tools.composio.servers.figma.description": "Figma 是一款用于网页和移动应用界面的协作设计工具。", + "tools.composio.servers.figma.readme": "连接 Figma 以访问设计文件并协作项目。查看设计、导出资源、浏览组件,并通过自然对话管理设计流程。", + "tools.composio.servers.github.description": "增强版 GitHub MCP 服务器", + "tools.composio.servers.github.readme": "连接 GitHub 以管理代码库、问题、拉取请求和代码。搜索代码、审查更改、创建分支,并通过对话式 AI 协作开发项目。", + "tools.composio.servers.gmail.description": "Gmail 是 Google 提供的免费电子邮件服务", + "tools.composio.servers.gmail.readme": "将 Gmail 的强大功能直接引入您的 AI 助手。阅读、撰写和发送邮件,搜索收件箱,管理标签,并通过自然对话组织您的通信。", + "tools.composio.servers.google-calendar.description": "Google 日历是一项时间管理和日程安排服务", + "tools.composio.servers.google-calendar.readme": "集成 Google 日历以无缝查看、创建和管理事件。安排会议、设置提醒、查看可用时间,并通过自然语言指令协调您的时间。", + "tools.composio.servers.google-docs.description": "Google 文档是 Google 提供的免费网页文字处理工具,属于 Google 文档编辑器套件的一部分", + "tools.composio.servers.google-docs.readme": "集成 Google 文档以创建、编辑和管理文档。撰写内容、格式化文本、实时协作,并通过自然对话访问您的文档。", + "tools.composio.servers.google-drive.description": "Google 云端硬盘是一项云存储服务", + "tools.composio.servers.google-drive.readme": "连接 Google 云端硬盘以访问、组织和管理您的文件。搜索文档、上传文件、共享内容,并通过 AI 助手高效导航您的云存储。", + "tools.composio.servers.google-sheets.description": "Google 表格是一款基于网页的电子表格应用,允许用户在线创建、编辑和协作处理表格", + "tools.composio.servers.google-sheets.readme": "连接 Google 表格以读取、编写和分析表格数据。执行计算、生成报告、创建图表,并通过 AI 协作管理表格数据。", + "tools.composio.servers.hubspot.description": "HubSpot 是一家专注于入站营销、销售和客户服务的软件开发商", + "tools.composio.servers.hubspot.readme": "集成 HubSpot 以管理联系人、交易和营销活动。访问 CRM 数据、跟踪销售流程、自动化工作流,并优化销售与营销操作。", + "tools.composio.servers.jira.description": "Jira 是由 Atlassian 开发的项目管理和问题跟踪工具", + "tools.composio.servers.jira.readme": "集成 Jira 以管理问题、跟踪进度并组织冲刺。创建工单、更新状态、查询项目数据,并通过自然对话优化开发流程。", + "tools.composio.servers.notion.description": "Notion 是一款协作型效率与笔记应用", + "tools.composio.servers.notion.readme": "连接 Notion 以访问和管理您的工作区。创建页面、搜索内容、更新数据库,并通过与 AI 助手的自然对话组织知识库。", + "tools.composio.servers.onedrive.description": "OneDrive 是由微软运营的文件托管和同步服务", + "tools.composio.servers.onedrive.readme": "连接 OneDrive 以访问和管理您的微软云文件。上传、下载、共享文件,组织文件夹,并通过 AI 助手协作处理文档。", + "tools.composio.servers.outlook-mail.description": "Outlook 邮件是微软提供的基于网页的邮件、联系人、任务和日历服务套件。", + "tools.composio.servers.outlook-mail.readme": "集成 Outlook 邮件以阅读、发送和管理您的微软邮件。搜索消息、撰写邮件、管理文件夹,并通过自然对话整理收件箱。", + "tools.composio.servers.salesforce.description": "Salesforce 是全球领先的客户关系管理(CRM)平台,帮助企业与客户、合作伙伴和潜在客户建立联系", + "tools.composio.servers.salesforce.readme": "连接 Salesforce 以管理客户关系和销售数据。查询记录、更新商机、跟踪潜在客户,并通过自然语言指令自动化 CRM 工作流。", + "tools.composio.servers.slack.description": "Slack 是一款为企业设计的消息应用,帮助人们获取所需信息", + "tools.composio.servers.slack.readme": "集成 Slack 以发送消息、搜索对话并管理频道。与团队连接、自动化沟通流程,并通过自然语言访问工作区信息。", + "tools.composio.servers.supabase.description": "Supabase 官方 MCP 服务器", + "tools.composio.servers.supabase.readme": "集成 Supabase 以管理数据库和后端服务。查询数据、管理身份验证、处理存储,并通过自然对话与应用后端交互。", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API 集成,支持发送文本、媒体并管理客户对话。适用于客户支持、营销活动和通过官方 WhatsApp Business 平台实现的自动化消息工作流。", + "tools.composio.servers.whatsapp.readme": "集成 WhatsApp Business 以发送消息、管理对话并与客户互动。通过对话式 AI 自动化消息流程并处理通信。", + "tools.composio.servers.youtube.description": "YouTube 是一个视频分享平台,用户可以上传、分享和发现内容。可编程访问视频信息、字幕和元数据。", + "tools.composio.servers.youtube.readme": "连接 YouTube 以搜索视频、访问字幕并获取视频信息。分析内容、提取元数据,并通过自然对话发现视频。", + "tools.composio.servers.zendesk.description": "Zendesk 是一家客户服务软件公司", + "tools.composio.servers.zendesk.readme": "集成 Zendesk 以管理支持工单和客户互动。创建、更新和跟踪支持请求,访问客户数据,并优化您的客服流程。", + "tools.composio.tools": "个工具", + "tools.composio.verifyAuth": "我已完成认证", "tools.lobehubSkill.authorize": "授权", "tools.lobehubSkill.connect": "连接", "tools.lobehubSkill.connected": "已连接", diff --git a/locales/zh-TW/setting.json b/locales/zh-TW/setting.json index d9d9d5d0a38..d77b8aee0c7 100644 --- a/locales/zh-TW/setting.json +++ b/locales/zh-TW/setting.json @@ -1170,77 +1170,74 @@ "tools.builtins.uninstallConfirm.title": "解除安裝 {{name}}", "tools.builtins.uninstalled": "已解除安裝", "tools.disabled": "當前模型不支持函數調用,無法使用插件", - "tools.klavis.addServer": "新增伺服器", - "tools.klavis.authCompleted": "驗證完成", - "tools.klavis.authFailed": "驗證失敗", - "tools.klavis.authRequired": "需要驗證", - "tools.klavis.connect": "連線", - "tools.klavis.connected": "已連線", - "tools.klavis.disconnect": "中斷連線", - "tools.klavis.disconnected": "已中斷連線", - "tools.klavis.error": "錯誤", - "tools.klavis.groupName": "Klavis 工具", - "tools.klavis.manage": "管理 Klavis", - "tools.klavis.manageTitle": "管理 Klavis 整合", - "tools.klavis.noServers": "尚未連線任何伺服器", - "tools.klavis.notEnabled": "Klavis 服務未啟用", - "tools.klavis.oauthRequired": "請在新視窗中完成 OAuth 驗證", - "tools.klavis.pendingAuth": "待驗證", - "tools.klavis.remove": "移除", - "tools.klavis.removeConfirm.desc": "{{name}} 將永久從您的連接服務中移除。此操作無法撤銷。", - "tools.klavis.removeConfirm.title": "移除 {{name}}?", - "tools.klavis.serverCreated": "伺服器建立成功", - "tools.klavis.serverCreatedFailed": "伺服器建立失敗", - "tools.klavis.serverRemoved": "伺服器已刪除", - "tools.klavis.servers": "個伺服器", - "tools.klavis.servers.airtable.description": "Airtable 是一個雲端資料庫與試算表平台,結合了試算表的彈性與資料庫的強大功能,讓團隊能以自訂視圖與自動化功能來組織、追蹤並協作專案。", - "tools.klavis.servers.airtable.readme": "整合 Airtable 以管理資料庫與工作流程。查詢紀錄、建立項目、更新資料,並透過自訂檢視與強大的追蹤功能自動化操作。", - "tools.klavis.servers.cal-com.description": "Cal.com 是一個開源排程平台,協助您免去來回溝通的麻煩,輕鬆安排會議。可管理事件類型、預約、可用時間,並與行事曆整合以實現無縫排程。", - "tools.klavis.servers.cal-com.readme": "連接 Cal.com 以管理排程與預約。查看可用時段、預訂會議、管理活動類型,並透過自然語言對話自動化行事曆。", - "tools.klavis.servers.clickup.description": "ClickUp 是一個全方位的專案管理與生產力平台,協助團隊以自訂工作流程與強大追蹤功能來組織任務、管理專案並有效協作。", - "tools.klavis.servers.clickup.readme": "連接 ClickUp 以管理任務、追蹤專案並組織工作。建立任務、更新狀態、管理自訂工作流程,並透過自然語言指令與團隊協作。", - "tools.klavis.servers.confluence.description": "Confluence 是一個結合知識與協作的團隊工作空間。", - "tools.klavis.servers.confluence.readme": "連接 Confluence 以存取與管理團隊文件。搜尋頁面、建立內容、組織空間,並透過對話式 AI 協助建立知識庫。", - "tools.klavis.servers.dropbox.description": "Dropbox 雲端儲存的完整檔案管理解決方案。可上傳、下載、組織檔案與資料夾、管理分享與協作、處理檔案版本、建立檔案請求,並對檔案與資料夾進行批次操作。", - "tools.klavis.servers.dropbox.readme": "整合 Dropbox 以存取與管理檔案。上傳、下載、分享檔案,管理資料夾、處理檔案版本,並透過對話式 AI 整理雲端儲存空間。", - "tools.klavis.servers.figma.description": "Figma 是一款用於網頁與行動應用程式的協作式介面設計工具。", - "tools.klavis.servers.figma.readme": "連接 Figma 以存取設計檔案並協作專案。檢視設計、匯出資產、瀏覽元件,並透過自然語言對話管理設計流程。", - "tools.klavis.servers.github.description": "增強版 GitHub MCP 伺服器", - "tools.klavis.servers.github.readme": "連接 GitHub 以管理儲存庫、議題、拉取請求與程式碼。搜尋程式碼、審查變更、建立分支,並透過對話式 AI 協作開發專案。", - "tools.klavis.servers.gmail.description": "Gmail 是 Google 提供的免費電子郵件服務", - "tools.klavis.servers.gmail.readme": "將 Gmail 的強大功能帶入您的 AI 助理。閱讀、撰寫與傳送電子郵件,搜尋收件匣、管理標籤,並透過自然語言對話整理通訊內容。", - "tools.klavis.servers.google-calendar.description": "Google 日曆是一項時間管理與排程服務", - "tools.klavis.servers.google-calendar.readme": "整合 Google 日曆以無縫檢視、建立與管理事件。排定會議、設定提醒、查看可用時段,並透過自然語言指令協調時間。", - "tools.klavis.servers.google-docs.description": "Google 文件是 Google Docs 編輯器套件中的線上文書處理工具", - "tools.klavis.servers.google-docs.readme": "整合 Google 文件以建立、編輯與管理文件。撰寫內容、格式化文字、即時協作,並透過自然語言對話存取文件。", - "tools.klavis.servers.google-drive.description": "Google 雲端硬碟是一項雲端儲存服務", - "tools.klavis.servers.google-drive.readme": "連接 Google 雲端硬碟以存取、整理與管理檔案。搜尋文件、上傳檔案、分享內容,並透過 AI 協助高效瀏覽雲端儲存空間。", - "tools.klavis.servers.google-sheets.description": "Google 試算表是一款網頁版試算表應用程式,讓使用者可線上建立、編輯與協作試算表", - "tools.klavis.servers.google-sheets.readme": "連接 Google 試算表以讀取、寫入與分析表格資料。執行計算、產生報告、建立圖表,並透過 AI 協助協作管理表格資料。", - "tools.klavis.servers.hubspot.description": "HubSpot 是一間開發行銷、自動化與客服軟體的公司", - "tools.klavis.servers.hubspot.readme": "整合 HubSpot 以管理聯絡人、交易與行銷活動。存取 CRM 資料、追蹤銷售流程、自動化工作流程,並簡化銷售與行銷操作。", - "tools.klavis.servers.jira.description": "Jira 是 Atlassian 開發的專案管理與問題追蹤工具", - "tools.klavis.servers.jira.readme": "整合 Jira 以管理問題、追蹤進度與組織衝刺。建立票據、更新狀態、查詢專案資料,並透過自然語言對話簡化開發流程。", - "tools.klavis.servers.notion.description": "Notion 是一款協作式生產力與筆記應用程式", - "tools.klavis.servers.notion.readme": "連接 Notion 以存取與管理工作區。建立頁面、搜尋內容、更新資料庫,並透過與 AI 助理的自然對話組織知識庫。", - "tools.klavis.servers.onedrive.description": "OneDrive 是由 Microsoft 提供的檔案託管與同步服務", - "tools.klavis.servers.onedrive.readme": "連接 OneDrive 以存取與管理 Microsoft 雲端檔案。上傳、下載、分享檔案、整理資料夾,並透過 AI 協助協作文件。", - "tools.klavis.servers.outlook-mail.description": "Outlook Mail 是 Microsoft 提供的網頁郵件、聯絡人、任務與行事曆服務套件", - "tools.klavis.servers.outlook-mail.readme": "整合 Outlook 郵件以閱讀、傳送與管理 Microsoft 電子郵件。搜尋訊息、撰寫郵件、管理資料夾,並透過自然語言對話整理收件匣。", - "tools.klavis.servers.salesforce.description": "Salesforce 是全球領先的客戶關係管理(CRM)平台,協助企業與客戶、合作夥伴及潛在客戶建立連結", - "tools.klavis.servers.salesforce.readme": "連接 Salesforce 以管理客戶關係與銷售資料。查詢紀錄、更新商機、追蹤潛在客戶,並透過自然語言指令自動化 CRM 工作流程。", - "tools.klavis.servers.slack.description": "Slack 是一款商業通訊應用程式,讓人們能快速取得所需資訊", - "tools.klavis.servers.slack.readme": "整合 Slack 以傳送訊息、搜尋對話與管理頻道。與團隊連結、自動化通訊流程,並透過自然語言存取工作區資訊。", - "tools.klavis.servers.supabase.description": "Supabase 官方 MCP 伺服器", - "tools.klavis.servers.supabase.readme": "整合 Supabase 以管理資料庫與後端服務。查詢資料、管理驗證、處理儲存空間,並透過自然語言對話與應用程式後端互動。", - "tools.klavis.servers.whatsapp.description": "WhatsApp Business API 整合,支援傳送文字訊息、媒體與管理客戶對話。適用於客服、行銷活動與自動化訊息流程,透過官方 WhatsApp Business 平台實現。", - "tools.klavis.servers.whatsapp.readme": "整合 WhatsApp Business 以傳送訊息、管理對話並與客戶互動。自動化訊息流程,並透過對話式 AI 處理通訊。", - "tools.klavis.servers.youtube.description": "YouTube 是一個影片分享平台,使用者可上傳、分享與探索內容。可程式化存取影片資訊、字幕與中繼資料。", - "tools.klavis.servers.youtube.readme": "連接 YouTube 以搜尋影片、存取字幕與擷取影片資訊。分析內容、提取中繼資料,並透過自然語言對話探索影片。", - "tools.klavis.servers.zendesk.description": "Zendesk 是一間提供客服軟體的公司", - "tools.klavis.servers.zendesk.readme": "整合 Zendesk 以管理支援票據與客戶互動。建立、更新與追蹤支援請求,存取客戶資料,並簡化客服作業流程。", - "tools.klavis.tools": "個工具", - "tools.klavis.verifyAuth": "我已完成驗證", + "tools.composio.addServer": "新增伺服器", + "tools.composio.authCompleted": "驗證完成", + "tools.composio.authFailed": "驗證失敗", + "tools.composio.authRequired": "需要驗證", + "tools.composio.connect": "連線", + "tools.composio.connected": "已連線", + "tools.composio.disconnect": "中斷連線", + "tools.composio.disconnected": "已中斷連線", + "tools.composio.error": "錯誤", + "tools.composio.groupName": "Composio 工具", + "tools.composio.manage": "管理 Composio", + "tools.composio.manageTitle": "管理 Composio 整合", + "tools.composio.noServers": "尚未連線任何伺服器", + "tools.composio.notEnabled": "Composio 服務未啟用", + "tools.composio.oauthRequired": "請在新視窗中完成 OAuth 驗證", + "tools.composio.pendingAuth": "待驗證", + "tools.composio.serverCreated": "伺服器建立成功", + "tools.composio.serverCreatedFailed": "伺服器建立失敗", + "tools.composio.serverRemoved": "伺服器已刪除", + "tools.composio.servers": "個伺服器", + "tools.composio.servers.airtable.description": "Airtable 是一個雲端資料庫與試算表平台,結合了試算表的彈性與資料庫的強大功能,讓團隊能以自訂視圖與自動化功能來組織、追蹤並協作專案。", + "tools.composio.servers.airtable.readme": "整合 Airtable 以管理資料庫與工作流程。查詢紀錄、建立項目、更新資料,並透過自訂檢視與強大的追蹤功能自動化操作。", + "tools.composio.servers.cal-com.description": "Cal.com 是一個開源排程平台,協助您免去來回溝通的麻煩,輕鬆安排會議。可管理事件類型、預約、可用時間,並與行事曆整合以實現無縫排程。", + "tools.composio.servers.cal-com.readme": "連接 Cal.com 以管理排程與預約。查看可用時段、預訂會議、管理活動類型,並透過自然語言對話自動化行事曆。", + "tools.composio.servers.clickup.description": "ClickUp 是一個全方位的專案管理與生產力平台,協助團隊以自訂工作流程與強大追蹤功能來組織任務、管理專案並有效協作。", + "tools.composio.servers.clickup.readme": "連接 ClickUp 以管理任務、追蹤專案並組織工作。建立任務、更新狀態、管理自訂工作流程,並透過自然語言指令與團隊協作。", + "tools.composio.servers.confluence.description": "Confluence 是一個結合知識與協作的團隊工作空間。", + "tools.composio.servers.confluence.readme": "連接 Confluence 以存取與管理團隊文件。搜尋頁面、建立內容、組織空間,並透過對話式 AI 協助建立知識庫。", + "tools.composio.servers.dropbox.description": "Dropbox 雲端儲存的完整檔案管理解決方案。可上傳、下載、組織檔案與資料夾、管理分享與協作、處理檔案版本、建立檔案請求,並對檔案與資料夾進行批次操作。", + "tools.composio.servers.dropbox.readme": "整合 Dropbox 以存取與管理檔案。上傳、下載、分享檔案,管理資料夾、處理檔案版本,並透過對話式 AI 整理雲端儲存空間。", + "tools.composio.servers.figma.description": "Figma 是一款用於網頁與行動應用程式的協作式介面設計工具。", + "tools.composio.servers.figma.readme": "連接 Figma 以存取設計檔案並協作專案。檢視設計、匯出資產、瀏覽元件,並透過自然語言對話管理設計流程。", + "tools.composio.servers.github.description": "增強版 GitHub MCP 伺服器", + "tools.composio.servers.github.readme": "連接 GitHub 以管理儲存庫、議題、拉取請求與程式碼。搜尋程式碼、審查變更、建立分支,並透過對話式 AI 協作開發專案。", + "tools.composio.servers.gmail.description": "Gmail 是 Google 提供的免費電子郵件服務", + "tools.composio.servers.gmail.readme": "將 Gmail 的強大功能帶入您的 AI 助理。閱讀、撰寫與傳送電子郵件,搜尋收件匣、管理標籤,並透過自然語言對話整理通訊內容。", + "tools.composio.servers.google-calendar.description": "Google 日曆是一項時間管理與排程服務", + "tools.composio.servers.google-calendar.readme": "整合 Google 日曆以無縫檢視、建立與管理事件。排定會議、設定提醒、查看可用時段,並透過自然語言指令協調時間。", + "tools.composio.servers.google-docs.description": "Google 文件是 Google Docs 編輯器套件中的線上文書處理工具", + "tools.composio.servers.google-docs.readme": "整合 Google 文件以建立、編輯與管理文件。撰寫內容、格式化文字、即時協作,並透過自然語言對話存取文件。", + "tools.composio.servers.google-drive.description": "Google 雲端硬碟是一項雲端儲存服務", + "tools.composio.servers.google-drive.readme": "連接 Google 雲端硬碟以存取、整理與管理檔案。搜尋文件、上傳檔案、分享內容,並透過 AI 協助高效瀏覽雲端儲存空間。", + "tools.composio.servers.google-sheets.description": "Google 試算表是一款網頁版試算表應用程式,讓使用者可線上建立、編輯與協作試算表", + "tools.composio.servers.google-sheets.readme": "連接 Google 試算表以讀取、寫入與分析表格資料。執行計算、產生報告、建立圖表,並透過 AI 協助協作管理表格資料。", + "tools.composio.servers.hubspot.description": "HubSpot 是一間開發行銷、自動化與客服軟體的公司", + "tools.composio.servers.hubspot.readme": "整合 HubSpot 以管理聯絡人、交易與行銷活動。存取 CRM 資料、追蹤銷售流程、自動化工作流程,並簡化銷售與行銷操作。", + "tools.composio.servers.jira.description": "Jira 是 Atlassian 開發的專案管理與問題追蹤工具", + "tools.composio.servers.jira.readme": "整合 Jira 以管理問題、追蹤進度與組織衝刺。建立票據、更新狀態、查詢專案資料,並透過自然語言對話簡化開發流程。", + "tools.composio.servers.notion.description": "Notion 是一款協作式生產力與筆記應用程式", + "tools.composio.servers.notion.readme": "連接 Notion 以存取與管理工作區。建立頁面、搜尋內容、更新資料庫,並透過與 AI 助理的自然對話組織知識庫。", + "tools.composio.servers.onedrive.description": "OneDrive 是由 Microsoft 提供的檔案託管與同步服務", + "tools.composio.servers.onedrive.readme": "連接 OneDrive 以存取與管理 Microsoft 雲端檔案。上傳、下載、分享檔案、整理資料夾,並透過 AI 協助協作文件。", + "tools.composio.servers.outlook-mail.description": "Outlook Mail 是 Microsoft 提供的網頁郵件、聯絡人、任務與行事曆服務套件", + "tools.composio.servers.outlook-mail.readme": "整合 Outlook 郵件以閱讀、傳送與管理 Microsoft 電子郵件。搜尋訊息、撰寫郵件、管理資料夾,並透過自然語言對話整理收件匣。", + "tools.composio.servers.salesforce.description": "Salesforce 是全球領先的客戶關係管理(CRM)平台,協助企業與客戶、合作夥伴及潛在客戶建立連結", + "tools.composio.servers.salesforce.readme": "連接 Salesforce 以管理客戶關係與銷售資料。查詢紀錄、更新商機、追蹤潛在客戶,並透過自然語言指令自動化 CRM 工作流程。", + "tools.composio.servers.slack.description": "Slack 是一款商業通訊應用程式,讓人們能快速取得所需資訊", + "tools.composio.servers.slack.readme": "整合 Slack 以傳送訊息、搜尋對話與管理頻道。與團隊連結、自動化通訊流程,並透過自然語言存取工作區資訊。", + "tools.composio.servers.supabase.description": "Supabase 官方 MCP 伺服器", + "tools.composio.servers.supabase.readme": "整合 Supabase 以管理資料庫與後端服務。查詢資料、管理驗證、處理儲存空間,並透過自然語言對話與應用程式後端互動。", + "tools.composio.servers.whatsapp.description": "WhatsApp Business API 整合,支援傳送文字訊息、媒體與管理客戶對話。適用於客服、行銷活動與自動化訊息流程,透過官方 WhatsApp Business 平台實現。", + "tools.composio.servers.whatsapp.readme": "整合 WhatsApp Business 以傳送訊息、管理對話並與客戶互動。自動化訊息流程,並透過對話式 AI 處理通訊。", + "tools.composio.servers.youtube.description": "YouTube 是一個影片分享平台,使用者可上傳、分享與探索內容。可程式化存取影片資訊、字幕與中繼資料。", + "tools.composio.servers.youtube.readme": "連接 YouTube 以搜尋影片、存取字幕與擷取影片資訊。分析內容、提取中繼資料,並透過自然語言對話探索影片。", + "tools.composio.servers.zendesk.description": "Zendesk 是一間提供客服軟體的公司", + "tools.composio.servers.zendesk.readme": "整合 Zendesk 以管理支援票據與客戶互動。建立、更新與追蹤支援請求,存取客戶資料,並簡化客服作業流程。", + "tools.composio.tools": "個工具", + "tools.composio.verifyAuth": "我已完成驗證", "tools.lobehubSkill.authorize": "授權", "tools.lobehubSkill.connect": "連接", "tools.lobehubSkill.connected": "已連線", diff --git a/package.json b/package.json index b9a7bf8d521..2c411b836df 100644 --- a/package.json +++ b/package.json @@ -193,6 +193,7 @@ "@chat-adapter/state-ioredis": "^4.23.0", "@chat-adapter/telegram": "^4.23.0", "@codesandbox/sandpack-react": "^2.20.0", + "@composio/core": "^0.10.0", "@discordjs/rest": "^2.6.0", "@dnd-kit/core": "^6.3.1", "@dnd-kit/sortable": "^10.0.0", @@ -369,7 +370,6 @@ "js-sha256": "^0.11.1", "jsondiffpatch": "^0.7.3", "jsonl-parse-stringify": "^1.0.3", - "klavis": "^2.15.0", "langfuse": "^3.38.6", "langfuse-core": "^3.38.6", "lexical": "0.42.0", diff --git a/packages/agent-manager-runtime/src/AgentManagerRuntime.ts b/packages/agent-manager-runtime/src/AgentManagerRuntime.ts index 563573afc85..b0fcc557911 100644 --- a/packages/agent-manager-runtime/src/AgentManagerRuntime.ts +++ b/packages/agent-manager-runtime/src/AgentManagerRuntime.ts @@ -14,7 +14,7 @@ * Services must be injected via constructor for runtime-agnostic usage * (e.g., server-side services vs client-side services). */ -import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; import { marketToolsResultsPrompt, modelsResultsPrompt } from '@lobechat/prompts'; import type { BuiltinToolResult } from '@lobechat/types'; @@ -24,11 +24,11 @@ import { getAiInfraStoreState } from '@/store/aiInfra'; import { getToolStoreState } from '@/store/tool'; import { builtinToolSelectors, - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore/types'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore/types'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import { getUserStoreState } from '@/store/user'; import { userProfileSelectors } from '@/store/user/selectors'; @@ -678,19 +678,19 @@ export class AgentManagerRuntime { const toolState = getToolStoreState(); if (source === 'official') { - // Check if it's a Klavis tool - const isKlavisEnabled = + // Check if it's a Composio tool + const isComposioEnabled = typeof window !== 'undefined' && - window.global_serverConfigStore?.getState()?.serverConfig?.enableKlavis; + window.global_serverConfigStore?.getState()?.serverConfig?.enableComposio; - if (isKlavisEnabled) { - const klavisServer = klavisStoreSelectors + if (isComposioEnabled) { + const composioServer = composioStoreSelectors .getServers(toolState) .find((s) => s.identifier === identifier); - const klavisTypeInfo = KLAVIS_SERVER_TYPES.find((t) => t.identifier === identifier); + const composioAppInfo = COMPOSIO_APP_TYPES.find((t) => t.identifier === identifier); - if (klavisTypeInfo) { - return this.handleKlavisInstall(agentId, identifier, klavisTypeInfo, klavisServer); + if (composioAppInfo) { + return this.handleComposioInstall(agentId, identifier, composioAppInfo, composioServer); } } @@ -777,39 +777,42 @@ export class AgentManagerRuntime { } } - private async handleKlavisInstall( + private async handleComposioInstall( agentId: string, identifier: string, - klavisTypeInfo: (typeof KLAVIS_SERVER_TYPES)[0], - klavisServer: any, + composioAppInfo: (typeof COMPOSIO_APP_TYPES)[0], + composioServer: any, ): Promise { - if (klavisServer) { - if (klavisServer.status === KlavisServerStatus.CONNECTED) { + if (composioServer) { + if (composioServer.status === ComposioServerStatus.ACTIVE) { await this.enablePluginForAgent(agentId, identifier); return { - content: `Successfully enabled Klavis tool: ${klavisTypeInfo.label}`, + content: `Successfully enabled Composio tool: ${composioAppInfo.label}`, state: { installed: true, - isKlavis: true, + isComposio: true, pluginId: identifier, - pluginName: klavisTypeInfo.label, + pluginName: composioAppInfo.label, serverStatus: 'connected', success: true, } as InstallPluginState, success: true, }; - } else if (klavisServer.status === KlavisServerStatus.PENDING_AUTH) { - if (klavisServer.oauthUrl) { - const authResult = await this.openOAuthWindowAndWait(klavisServer.oauthUrl, identifier); + } else if (composioServer.status === ComposioServerStatus.PENDING_AUTH) { + if (composioServer.redirectUrl) { + const authResult = await this.openOAuthWindowAndWait( + composioServer.redirectUrl, + identifier, + ); if (authResult.success) { await this.enablePluginForAgent(agentId, identifier); return { - content: `Successfully connected and enabled Klavis tool: ${klavisTypeInfo.label}`, + content: `Successfully connected and enabled Composio tool: ${composioAppInfo.label}`, state: { installed: true, - isKlavis: true, + isComposio: true, pluginId: identifier, - pluginName: klavisTypeInfo.label, + pluginName: composioAppInfo.label, serverStatus: 'connected', success: true, } as InstallPluginState, @@ -818,12 +821,12 @@ export class AgentManagerRuntime { } } return { - content: `OAuth authorization was cancelled or failed for Klavis tool: ${klavisTypeInfo.label}. Please try again.`, + content: `OAuth authorization was cancelled or failed for Composio tool: ${composioAppInfo.label}. Please try again.`, state: { installed: false, - isKlavis: true, + isComposio: true, pluginId: identifier, - pluginName: klavisTypeInfo.label, + pluginName: composioAppInfo.label, serverStatus: 'pending_auth', success: false, } as InstallPluginState, @@ -836,53 +839,52 @@ export class AgentManagerRuntime { const userId = userProfileSelectors.userId(getUserStoreState()); if (!userId) { return { - content: `Cannot connect Klavis tool: User not logged in.`, + content: `Cannot connect Composio tool: User not logged in.`, error: { message: 'User not logged in', type: 'AuthRequired' }, - state: { - installed: false, - pluginId: identifier, - success: false, - } as InstallPluginState, + state: { installed: false, pluginId: identifier, success: false } as InstallPluginState, success: false, }; } - const newServer = await getToolStoreState().createKlavisServer({ + const newServer = await getToolStoreState().createComposioConnection({ + appSlug: composioAppInfo.appSlug, identifier, - serverName: klavisTypeInfo.serverName, - userId, + label: composioAppInfo.label, }); if (newServer) { - await this.enablePluginForAgent(agentId, identifier); - - if (newServer.isAuthenticated) { - await getToolStoreState().refreshKlavisServerTools(newServer.identifier); + // Enable the plugin only once the connection is actually usable. Enabling + // before OAuth completes would leave an enabled-but-unauthorized tool on + // the agent if the user cancels the authorization. + if (newServer.status === ComposioServerStatus.ACTIVE) { + await this.enablePluginForAgent(agentId, identifier); + await getToolStoreState().refreshComposioConnectionStatus(newServer.identifier); return { - content: `Successfully connected and enabled Klavis tool: ${klavisTypeInfo.label}`, + content: `Successfully connected and enabled Composio tool: ${composioAppInfo.label}`, state: { installed: true, - isKlavis: true, + isComposio: true, pluginId: identifier, - pluginName: klavisTypeInfo.label, + pluginName: composioAppInfo.label, serverStatus: 'connected', success: true, } as InstallPluginState, success: true, }; - } else if (newServer.oauthUrl) { + } else if (newServer.redirectUrl) { const authResult = await this.openOAuthWindowAndWait( - newServer.oauthUrl, + newServer.redirectUrl, newServer.identifier, ); if (authResult.success) { + await this.enablePluginForAgent(agentId, identifier); return { - content: `Successfully connected and enabled Klavis tool: ${klavisTypeInfo.label}`, + content: `Successfully connected and enabled Composio tool: ${composioAppInfo.label}`, state: { installed: true, - isKlavis: true, + isComposio: true, pluginId: identifier, - pluginName: klavisTypeInfo.label, + pluginName: composioAppInfo.label, serverStatus: 'connected', success: true, } as InstallPluginState, @@ -893,8 +895,8 @@ export class AgentManagerRuntime { } return { - content: `Failed to connect Klavis tool: ${klavisTypeInfo.label}`, - error: { message: 'Failed to create Klavis server', type: 'KlavisError' }, + content: `Failed to connect Composio tool: ${composioAppInfo.label}`, + error: { message: 'Failed to create Composio connection', type: 'ComposioError' }, state: { installed: false, pluginId: identifier, @@ -1052,17 +1054,17 @@ export class AgentManagerRuntime { } private openOAuthWindowAndWait( - oauthUrl: string, + redirectUrl: string, identifier: string, ): Promise<{ cancelled: boolean; success: boolean }> { const checkAuthStatus = async (): Promise => { try { - await getToolStoreState().refreshKlavisServerTools(identifier); + await getToolStoreState().refreshComposioConnectionStatus(identifier); const freshToolStore = getToolStoreState(); - const server = klavisStoreSelectors + const server = composioStoreSelectors .getServers(freshToolStore) .find((s) => s.identifier === identifier); - return server?.status === KlavisServerStatus.CONNECTED; + return server?.status === ComposioServerStatus.ACTIVE; } catch { return false; } @@ -1103,7 +1105,7 @@ export class AgentManagerRuntime { ); }; - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { windowCheckInterval = setInterval(async () => { @@ -1125,7 +1127,7 @@ export class AgentManagerRuntime { } private openLobehubSkillOAuthWindowAndWait( - oauthUrl: string, + redirectUrl: string, provider: string, ): Promise<{ cancelled: boolean; success: boolean }> { const checkAuthStatus = async (): Promise => { @@ -1188,7 +1190,7 @@ export class AgentManagerRuntime { ); }; - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { windowCheckInterval = setInterval(async () => { diff --git a/packages/agent-manager-runtime/src/__tests__/AgentManagerRuntime.test.ts b/packages/agent-manager-runtime/src/__tests__/AgentManagerRuntime.test.ts index 269235a9e5f..6c88384ab55 100644 --- a/packages/agent-manager-runtime/src/__tests__/AgentManagerRuntime.test.ts +++ b/packages/agent-manager-runtime/src/__tests__/AgentManagerRuntime.test.ts @@ -85,7 +85,7 @@ vi.mock('@/store/tool/selectors', () => ({ builtinToolSelectors: { metaList: vi.fn(() => [{ identifier: 'lobe-web-browsing', meta: { title: 'Web Browsing' } }]), }, - klavisStoreSelectors: { + composioStoreSelectors: { getServers: vi.fn(() => []), }, lobehubSkillStoreSelectors: { diff --git a/packages/agent-manager-runtime/src/types.ts b/packages/agent-manager-runtime/src/types.ts index 765356cb1c4..b336e4e19de 100644 --- a/packages/agent-manager-runtime/src/types.ts +++ b/packages/agent-manager-runtime/src/types.ts @@ -236,11 +236,11 @@ export interface InstallPluginState { awaitingApproval?: boolean; error?: string; installed: boolean; - isKlavis?: boolean; + isComposio?: boolean; isLobehubSkill?: boolean; - oauthUrl?: string; pluginId: string; pluginName?: string; + redirectUrl?: string; serverName?: string; serverStatus?: 'connected' | 'pending_auth' | 'error' | 'not_connected'; success: boolean; diff --git a/packages/app-config/src/composio.ts b/packages/app-config/src/composio.ts new file mode 100644 index 00000000000..1227122dd2b --- /dev/null +++ b/packages/app-config/src/composio.ts @@ -0,0 +1,51 @@ +import { createEnv } from '@t3-oss/env-nextjs'; +import { z } from 'zod'; + +export const getComposioConfig = () => { + return createEnv({ + client: {}, + runtimeEnv: { + COMPOSIO_API_KEY: process.env.COMPOSIO_API_KEY, + COMPOSIO_AUTH_CONFIG_IDS: process.env.COMPOSIO_AUTH_CONFIG_IDS, + }, + server: { + COMPOSIO_API_KEY: z.string().optional(), + /** + * JSON map of `identifier -> authConfigId`, pinning a pre-created (e.g. + * custom/white-label) Composio auth config per toolkit. Example: + * `{"gmail":"ac_rc8q_6L4kL-I","google-calendar":"ac_..."}`. + * When an identifier is present here, that auth config is used directly + * instead of auto-creating a Composio-managed one. + */ + COMPOSIO_AUTH_CONFIG_IDS: z.string().optional(), + }, + }); +}; + +export const composioEnv = getComposioConfig(); + +export const getServerComposioApiKey = (): string | undefined => { + if (typeof window !== 'undefined') { + console.error('[Composio] Attempted to access API key from client-side!'); + return undefined; + } + return composioEnv.COMPOSIO_API_KEY; +}; + +/** + * Resolve a pre-configured Composio auth config id for the given toolkit + * identifier (e.g. 'gmail'). Returns undefined when no pin is configured, in + * which case the caller falls back to discovering/creating an auth config. + */ +export const getServerComposioAuthConfigId = (identifier: string): string | undefined => { + if (typeof window !== 'undefined') return undefined; + const raw = composioEnv.COMPOSIO_AUTH_CONFIG_IDS; + if (!raw) return undefined; + try { + const map = JSON.parse(raw) as Record; + return map[identifier]; + } catch { + console.error('[Composio] COMPOSIO_AUTH_CONFIG_IDS is not valid JSON'); + return undefined; + } +}; diff --git a/packages/app-config/src/klavis.ts b/packages/app-config/src/klavis.ts deleted file mode 100644 index ec56d0f8ef3..00000000000 --- a/packages/app-config/src/klavis.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { createEnv } from '@t3-oss/env-nextjs'; -import { z } from 'zod'; - -/** - * Klavis Service Configuration - * - * Architecture: - * - Server-side: KLAVIS_API_KEY is stored and used only on the server - * - Client-side: Klavis enabled status is provided via serverConfig store (enableKlavis) - * - Client calls server APIs which use the API key - * - * Security: - * - API key is NEVER exposed to the client - * - Client gets enabled status from server config - */ -export const getKlavisConfig = () => { - return createEnv({ - client: {}, - runtimeEnv: { - // Server-side API key (never exposed to client) - KLAVIS_API_KEY: process.env.KLAVIS_API_KEY, - }, - server: { - KLAVIS_API_KEY: z.string().optional(), - }, - }); -}; - -export const klavisEnv = getKlavisConfig(); - -/** - * Get Klavis API Key (server-side only) - * IMPORTANT: This should only be called from server-side code - */ -export const getServerKlavisApiKey = (): string | undefined => { - if (typeof window !== 'undefined') { - console.error('[Klavis] Attempted to access API key from client-side!'); - return undefined; - } - return klavisEnv.KLAVIS_API_KEY; -}; diff --git a/packages/builtin-tool-activator/src/systemRole.ts b/packages/builtin-tool-activator/src/systemRole.ts index 835917c16d1..a3562a969c4 100644 --- a/packages/builtin-tool-activator/src/systemRole.ts +++ b/packages/builtin-tool-activator/src/systemRole.ts @@ -74,9 +74,9 @@ export const systemPrompt = `You have access to a Tools Activator that allows yo 3. If credential exists → use \`getPlaintextCred\` or \`injectCredsToSandbox\` (for sandbox execution) 4. If credential doesn't exist: - For LobeHub OAuth services (GitHub, Linear, Microsoft, Notion, Twitter) → use \`initiateOAuthConnect\` - - For Klavis-managed services (Slack, Google Drive, Airtable, Jira, etc.) - → use \`connectKlavisService\` after activating \`lobe-creds\`. The full list of - available Klavis services is shown in \`\` inside the + - For Composio-managed services (Slack, Google Drive, Airtable, Jira, etc.) + → use \`connectComposioService\` after activating \`lobe-creds\`. The full list of + available Composio services is shown in \`\` inside the lobe-creds system prompt. - For API keys/tokens → guide user to save with \`saveCreds\` 5. For sandbox code that needs credentials → use \`injectCredsToSandbox\` to inject them as environment variables diff --git a/packages/builtin-tool-agent-builder/src/client/Intervention/InstallPlugin.tsx b/packages/builtin-tool-agent-builder/src/client/Intervention/InstallPlugin.tsx index 5893a61667c..cc8f78142ee 100644 --- a/packages/builtin-tool-agent-builder/src/client/Intervention/InstallPlugin.tsx +++ b/packages/builtin-tool-agent-builder/src/client/Intervention/InstallPlugin.tsx @@ -1,6 +1,6 @@ 'use client'; -import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; import type { BuiltinInterventionProps } from '@lobechat/types'; import { Avatar, Flexbox } from '@lobehub/ui'; import { CheckCircle } from 'lucide-react'; @@ -9,12 +9,12 @@ import { useTranslation } from 'react-i18next'; import { useToolStore } from '@/store/tool'; import { - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, mcpStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore/types'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore/types'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import type { InstallPluginParams } from '../../types'; @@ -34,9 +34,9 @@ const InstallPluginIntervention = memo pluginSelectors.isPluginInstalled(identifier)(s)); - // Get Klavis server state - const klavisServer = useToolStore((s) => - klavisStoreSelectors.getServers(s).find((srv) => srv.identifier === identifier), + // Get Composio server state + const composioServer = useToolStore((s) => + composioStoreSelectors.getServers(s).find((srv) => srv.identifier === identifier), ); // Get LobehubSkill server state @@ -52,9 +52,9 @@ const InstallPluginIntervention = memo tool.identifier === identifier), ); - // Check if it's a Klavis tool - const klavisTypeInfo = KLAVIS_SERVER_TYPES.find((t) => t.identifier === identifier); - const isKlavis = source === 'official' && !!klavisTypeInfo; + // Check if it's a Composio tool + const composioAppInfo = COMPOSIO_APP_TYPES.find((t) => t.identifier === identifier); + const isComposio = source === 'official' && !!composioAppInfo; // Check if it's a LobehubSkill provider const lobehubSkillProviderInfo = LOBEHUB_SKILL_PROVIDERS.find((p) => p.id === identifier); @@ -76,22 +76,22 @@ const InstallPluginIntervention = memo - {isKlavis || isLobehubSkill + {isComposio || isLobehubSkill ? t('agentBuilder.installPlugin.connectedAndEnabled') : t('agentBuilder.installPlugin.installedAndEnabled')} - {klavisTypeInfo?.label || lobehubSkillProviderInfo?.label || identifier} + {composioAppInfo?.label || lobehubSkillProviderInfo?.label || identifier} ); } - // Render Klavis tool - if (isKlavis) { - const icon = typeof klavisTypeInfo?.icon === 'string' ? klavisTypeInfo.icon : undefined; - const isPendingAuth = klavisServer?.status === KlavisServerStatus.PENDING_AUTH; + // Render Composio tool + if (isComposio) { + const icon = typeof composioAppInfo?.icon === 'string' ? composioAppInfo.icon : undefined; + const isPendingAuth = composioServer?.status === ComposioServerStatus.PENDING_AUTH; return ( {icon ? ( {klavisTypeInfo?.label - {klavisTypeInfo?.label || identifier} - Klavis + {composioAppInfo?.label || identifier} + Composio {isPendingAuth diff --git a/packages/builtin-tool-agent-builder/src/client/Render/InstallPlugin.tsx b/packages/builtin-tool-agent-builder/src/client/Render/InstallPlugin.tsx index e183099b4ed..5f807e1dc4c 100644 --- a/packages/builtin-tool-agent-builder/src/client/Render/InstallPlugin.tsx +++ b/packages/builtin-tool-agent-builder/src/client/Render/InstallPlugin.tsx @@ -14,7 +14,7 @@ const InstallPlugin = memo - {isKlavis || isLobehubSkill ? ( + {isComposio || isLobehubSkill ? ( <> Waiting for authorization:{' '} - {isKlavis || isLobehubSkill ? 'Connected and enabled' : 'Installed and enabled'}:{' '} + {isComposio || isLobehubSkill ? 'Connected and enabled' : 'Installed and enabled'}:{' '} @@ -46,7 +46,7 @@ You have access to tools that can modify agent configurations: - **getAvailableModels**: Get all available AI models and providers that can be used. Optionally filter by provider ID. - **searchMarketTools**: Search for tools (MCP plugins) in the marketplace. Shows results with install buttons for users to install directly. -Note: Official tools (built-in tools, Klavis MCP servers, and LobehubSkill providers) are automatically available in the \`\` - no need to search for them. +Note: Official tools (built-in tools, Composio MCP servers, and LobehubSkill providers) are automatically available in the \`\` - no need to search for them. **Write Operations:** - **updateConfig**: Update agent configuration fields (model, provider, plugins, and advanced settings). Use this for all config changes. @@ -222,7 +222,7 @@ User: "What tools are available in the marketplace?" Action: Use searchMarketTools without query to browse all available tools. Display the list with descriptions and install options. User: "帮我找一下有什么插件可以用" -Action: Reference the \`\` from the injected context to show available built-in tools, Klavis MCP servers, and LobehubSkill providers. This allows the user to enable tools directly or connect to services. +Action: Reference the \`\` from the injected context to show available built-in tools, Composio MCP servers, and LobehubSkill providers. This allows the user to enable tools directly or connect to services. User: "I want to connect my Linear" Action: Check the \`\` in the context for Linear LobehubSkill provider. If found, use installPlugin with source "official" to connect it. @@ -231,7 +231,7 @@ User: "帮我连接 Twitter" Action: Check the \`\` in the context for Twitter (X) LobehubSkill provider. If found, use installPlugin with source "official" to connect it. User: "What official integrations are available?" -Action: Reference the \`\` from the injected context to list all available integrations including built-in tools, Klavis MCP servers, and LobehubSkill providers (Linear, Outlook Calendar, Twitter, etc.). +Action: Reference the \`\` from the injected context to list all available integrations including built-in tools, Composio MCP servers, and LobehubSkill providers (Linear, Outlook Calendar, Twitter, etc.). User: "帮我设置开场白" / "Set an opening message for this agent" Action: Use updateConfig with { config: { openingMessage: "Hello! I'm your AI assistant. How can I help you today?" } } diff --git a/packages/builtin-tool-agent-builder/src/types.ts b/packages/builtin-tool-agent-builder/src/types.ts index ee6ad51cee3..6bc838a5d79 100644 --- a/packages/builtin-tool-agent-builder/src/types.ts +++ b/packages/builtin-tool-agent-builder/src/types.ts @@ -164,7 +164,7 @@ export interface InstallPluginParams { */ identifier: string; /** - * Plugin source type: 'market' for MCP marketplace, 'official' for builtin/klavis/lobehubSkill tools + * Plugin source type: 'market' for MCP marketplace, 'official' for builtin/composio/lobehubSkill tools */ source: 'market' | 'official'; } @@ -172,7 +172,7 @@ export interface InstallPluginParams { export interface InstallPluginState { /** * Whether the plugin requires human approval to continue installation - * (e.g., Klavis tools need OAuth connection) + * (e.g., Composio tools need OAuth connection) */ awaitingApproval?: boolean; /** @@ -184,17 +184,13 @@ export interface InstallPluginState { */ installed: boolean; /** - * Whether the plugin is a Klavis tool that needs OAuth connection + * Whether the plugin is a Composio tool that needs OAuth connection */ - isKlavis?: boolean; + isComposio?: boolean; /** * Whether the plugin is a LobehubSkill provider that needs OAuth connection */ isLobehubSkill?: boolean; - /** - * Klavis OAuth URL if authorization is needed - */ - oauthUrl?: string; /** * Plugin identifier */ @@ -204,11 +200,15 @@ export interface InstallPluginState { */ pluginName?: string; /** - * Klavis server name (for Klavis tools) + * Composio OAuth URL if authorization is needed + */ + redirectUrl?: string; + /** + * Composio server name (for Composio tools) */ serverName?: string; /** - * Server status (for Klavis tools and LobehubSkill providers) + * Server status (for Composio tools and LobehubSkill providers) */ serverStatus?: 'connected' | 'pending_auth' | 'error' | 'not_connected'; /** diff --git a/packages/builtin-tool-agent-management/src/manifest.ts b/packages/builtin-tool-agent-management/src/manifest.ts index 77c8c3152a7..3be4f41d68c 100644 --- a/packages/builtin-tool-agent-management/src/manifest.ts +++ b/packages/builtin-tool-agent-management/src/manifest.ts @@ -194,7 +194,7 @@ export const AgentManagementManifest: BuiltinToolManifest = { }, { description: - "Install a plugin/tool for an agent. Use 'official' source for builtin tools, Klavis integrations, and LobehubSkill providers. Use 'market' source for MCP marketplace plugins.", + "Install a plugin/tool for an agent. Use 'official' source for builtin tools, Composio integrations, and LobehubSkill providers. Use 'market' source for MCP marketplace plugins.", name: AgentManagementApiName.installPlugin, parameters: { properties: { @@ -208,7 +208,7 @@ export const AgentManagementManifest: BuiltinToolManifest = { }, source: { description: - "Plugin source: 'official' (builtin tools, Klavis, LobehubSkill) or 'market' (MCP marketplace)", + "Plugin source: 'official' (builtin tools, Composio, LobehubSkill) or 'market' (MCP marketplace)", enum: ['official', 'market'], type: 'string', }, diff --git a/packages/builtin-tool-agent-management/src/systemRole.ts b/packages/builtin-tool-agent-management/src/systemRole.ts index 234662bd49e..b6f6cb9cc23 100644 --- a/packages/builtin-tool-agent-management/src/systemRole.ts +++ b/packages/builtin-tool-agent-management/src/systemRole.ts @@ -23,7 +23,7 @@ export const systemPrompt = `You have Agent Management tools to create, configur - **updatePrompt**: Update an agent's system prompt directly (preferred over updateAgent when only changing the prompt) **Plugin Management:** -- **installPlugin**: Install a plugin/tool for an agent (builtin, Klavis, LobehubSkill, or MCP marketplace) +- **installPlugin**: Install a plugin/tool for an agent (builtin, Composio, LobehubSkill, or MCP marketplace) **Execution:** - **callAgent**: Invoke an agent to handle a task (synchronously or as async background task) @@ -36,7 +36,7 @@ When this tool is enabled, you will receive contextual information about: - **Current Agent**: Your own agent ID (in the \`\` tag). Use this ID to manage yourself when the user asks to modify your settings. - **Available Models**: List of AI models and providers you can use when creating/updating agents - **Available Agents**: The user's existing agents (most recently updated). You can call them directly via callAgent without first running searchAgent when one of them clearly matches the user's request. -- **Available Plugins**: List of plugins (builtin tools, Klavis integrations, LobehubSkill providers) you can enable for agents +- **Available Plugins**: List of plugins (builtin tools, Composio integrations, LobehubSkill providers) you can enable for agents This information is automatically injected into the conversation context. Use the exact IDs from the context when specifying model/provider/plugins/agentId parameters. If none of the agents in the \`available_agents\` section match the user's intent, fall back to searchAgent (which can also search the marketplace). @@ -125,7 +125,7 @@ You can specify plugins during agent creation using the \`plugins\` parameter: **Plugin types available:** - **Builtin tools**: Core system tools (e.g., web search, image generation) -- **Klavis integrations**: Third-party service integrations requiring OAuth +- **Composio integrations**: Third-party service integrations requiring OAuth - **LobehubSkill providers**: Advanced skill providers Refer to the injected context for available plugin IDs and descriptions. @@ -180,7 +180,7 @@ The duplicated agent inherits all configuration from the original. After duplica Use installPlugin to add tools/plugins to an agent: **Plugin Sources:** -- **official**: Builtin tools (e.g., web search, code sandbox), Klavis integrations (e.g., Gmail, Google Calendar), and LobehubSkill providers +- **official**: Builtin tools (e.g., web search, code sandbox), Composio integrations (e.g., Gmail, Google Calendar), and LobehubSkill providers - **market**: MCP marketplace plugins \`\`\` @@ -188,7 +188,7 @@ installPlugin(agentId, identifier, source) \`\`\` **Notes:** -- Some official plugins (Klavis, LobehubSkill) may require OAuth authorization +- Some official plugins (Composio, LobehubSkill) may require OAuth authorization - Use the available plugins from the injected context to find valid plugin identifiers - After installation, the plugin is automatically enabled for the specified agent diff --git a/packages/builtin-tool-agent-management/src/types.ts b/packages/builtin-tool-agent-management/src/types.ts index cc89744989d..128cc0a9ebe 100644 --- a/packages/builtin-tool-agent-management/src/types.ts +++ b/packages/builtin-tool-agent-management/src/types.ts @@ -383,7 +383,7 @@ export interface InstallPluginParams { */ identifier: string; /** - * Plugin source: 'official' (builtin/klavis/lobehub-skill) or 'market' (MCP marketplace) + * Plugin source: 'official' (builtin/composio/lobehub-skill) or 'market' (MCP marketplace) */ source: InstallPluginSource; } diff --git a/packages/builtin-tool-creds/src/ExecutionRuntime/index.ts b/packages/builtin-tool-creds/src/ExecutionRuntime/index.ts index 63d5ff47296..c0219835aa3 100644 --- a/packages/builtin-tool-creds/src/ExecutionRuntime/index.ts +++ b/packages/builtin-tool-creds/src/ExecutionRuntime/index.ts @@ -1,8 +1,8 @@ -import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; +import { getComposioAppByIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; import type { BuiltinServerRuntimeOutput } from '@lobechat/types'; import type { - ConnectKlavisServiceParams, + ConnectComposioServiceParams, InitiateOAuthConnectParams, InjectCredsToSandboxParams, SaveCredsParams, @@ -89,21 +89,21 @@ export class CredsExecutionRuntime { } /** - * Connect a Klavis integration service - * In server-side context, Klavis OAuth requires browser interaction, + * Connect a Composio integration service + * In server-side context, Composio OAuth requires browser interaction, * so we return a message guiding the user to connect via the UI. */ - async connectKlavisService( - args: ConnectKlavisServiceParams, + async connectComposioService( + args: ConnectComposioServiceParams, ): Promise { const { service } = args; - const serverType = getKlavisServerByServerIdentifier(service); + const serverType = getComposioAppByIdentifier(service); if (!serverType) { return { - content: `Unknown Klavis service: "${service}". Check the available Klavis services list in the credentials context.`, + content: `Unknown Composio service: "${service}". Check the available Composio services list in the credentials context.`, error: { - message: `Unknown Klavis service: ${service}`, + message: `Unknown Composio service: ${service}`, type: 'UnknownService', }, success: false, @@ -113,7 +113,7 @@ export class CredsExecutionRuntime { // Server-side cannot open OAuth popups or access browser stores. // Guide the user to connect via the frontend UI. return { - content: `To connect ${serverType.label}, please use the LobeHub app UI to initiate the Klavis OAuth flow. Server-side execution cannot open OAuth popups. Go to Settings or the onboarding page to connect ${serverType.label}.`, + content: `To connect ${serverType.label}, please use the LobeHub app UI to initiate the Composio OAuth flow. Server-side execution cannot open OAuth popups. Go to Settings or the onboarding page to connect ${serverType.label}.`, state: { connected: false, identifier: service, diff --git a/packages/builtin-tool-creds/src/executor/index.ts b/packages/builtin-tool-creds/src/executor/index.ts index aa2e8fe0ba1..a393d6db25d 100644 --- a/packages/builtin-tool-creds/src/executor/index.ts +++ b/packages/builtin-tool-creds/src/executor/index.ts @@ -1,18 +1,18 @@ -import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; +import { getComposioAppByIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; import type { BuiltinToolContext, BuiltinToolResult } from '@lobechat/types'; import { BaseExecutor } from '@lobechat/types'; import debug from 'debug'; import { lambdaClient, toolsClient } from '@/libs/trpc/client'; import { getToolStoreState, useToolStore } from '@/store/tool'; -import { klavisStoreSelectors } from '@/store/tool/selectors'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore/types'; +import { composioStoreSelectors } from '@/store/tool/selectors'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore/types'; import { useUserStore } from '@/store/user'; import { userProfileSelectors } from '@/store/user/slices/auth/selectors'; import { CredsIdentifier } from '../manifest'; import type { - ConnectKlavisServiceParams, + ConnectComposioServiceParams, InitiateOAuthConnectParams, InjectCredsToSandboxParams, SaveCredsParams, @@ -26,22 +26,22 @@ class CredsExecutor extends BaseExecutor { protected readonly apiEnum = CredsApiName; /** - * Connect a Klavis integration service via OAuth - * Creates a Klavis server instance and initiates the OAuth flow + * Connect a Composio integration service via OAuth + * Creates a Composio connection and initiates the OAuth flow */ - connectKlavisService = async ( - params: ConnectKlavisServiceParams, + connectComposioService = async ( + params: ConnectComposioServiceParams, _ctx?: BuiltinToolContext, ): Promise => { try { const { service } = params; // Validate service identifier - const serverType = getKlavisServerByServerIdentifier(service); - if (!serverType) { + const appType = getComposioAppByIdentifier(service); + if (!appType) { return { error: { - message: `Unknown Klavis service: "${service}". Check the available Klavis services list in the credentials context.`, + message: `Unknown Composio service: "${service}". Check the available Composio services list in the credentials context.`, type: 'UnknownService', }, success: false, @@ -50,85 +50,64 @@ class CredsExecutor extends BaseExecutor { // Check if already connected via store const toolState = getToolStoreState(); - const existingServer = klavisStoreSelectors.getServerByIdentifier(service)(toolState); - if (existingServer?.status === KlavisServerStatus.CONNECTED) { + const existingServer = composioStoreSelectors.getServerByIdentifier(service)(toolState); + if (existingServer?.status === ComposioServerStatus.ACTIVE) { return { - content: `Already connected to ${serverType.label}. You can use ${serverType.label} tools directly.`, + content: `Already connected to ${appType.label}. You can use ${appType.label} tools directly.`, state: { connected: true, identifier: service, - serviceName: serverType.label, + serviceName: appType.label, }, success: true, }; } - // Get userId - const userId = userProfileSelectors.userId(useUserStore.getState()); - if (!userId) { - return { - error: { - message: 'User is not authenticated', - type: 'MissingUserId', - }, - success: false, - }; - } + log('[CredsExecutor] connectComposioService - creating connection for:', service); - log('[CredsExecutor] connectKlavisService - creating server for:', service); - - // Create Klavis server instance - const server = await useToolStore.getState().createKlavisServer({ - identifier: serverType.identifier, - serverName: serverType.serverName, - userId, + // Create Composio connection (authConfigId managed server-side) + const server = await useToolStore.getState().createComposioConnection({ + appSlug: appType.appSlug, + identifier: appType.identifier, + label: appType.label, }); if (!server) { return { error: { - message: `Failed to create Klavis server instance for ${serverType.label}`, + message: `Failed to create Composio connection for ${appType.label}`, type: 'CreateServerFailed', }, success: false, }; } - // If already authenticated (no OAuth needed) - if (server.isAuthenticated) { + // If already active (no OAuth needed) + if (server.status === ComposioServerStatus.ACTIVE) { return { - content: `Successfully connected to ${serverType.label}! You can now use ${serverType.label} tools.`, + content: `Successfully connected to ${appType.label}! You can now use ${appType.label} tools.`, state: { connected: true, identifier: service, - serviceName: serverType.label, + serviceName: appType.label, }, success: true, }; } - // OAuth needed — open popup and poll for completion - if (server.oauthUrl) { - const result = await this.openKlavisOAuthAndWait(server.oauthUrl, server.identifier); - - if (result.success) { - return { - content: `Successfully connected to ${serverType.label}! You can now use ${serverType.label} tools.`, - state: { - connected: true, - identifier: service, - serviceName: serverType.label, - }, - success: true, - }; - } - + // OAuth needed — return the authorization link for the user to open. + // This tool runs from the agent's response, which carries no user gesture, + // so the browser would block any popup we tried to open ourselves. Handing + // back the link lets the user click it (a real gesture) to authorize; the + // connection moves to ACTIVE once they finish. + if (server.redirectUrl) { return { - content: `Authorization was cancelled or timed out for ${serverType.label}. You can try again later.`, + content: `To connect ${appType.label}, ask the user to open this authorization link and complete the sign-in:\n\n${server.redirectUrl}\n\nOnce they have authorized, ${appType.label} tools will be ready to use.`, state: { connected: false, identifier: service, - serviceName: serverType.label, + redirectUrl: server.redirectUrl, + serviceName: appType.label, }, success: true, }; @@ -136,17 +115,17 @@ class CredsExecutor extends BaseExecutor { return { error: { - message: 'Unexpected server state: no oauthUrl and not authenticated', + message: 'Unexpected server state: no redirectUrl and not active', type: 'UnexpectedState', }, success: false, }; } catch (error) { - log('[CredsExecutor] connectKlavisService - error:', error); + log('[CredsExecutor] connectComposioService - error:', error); return { error: { - message: error instanceof Error ? error.message : 'Failed to connect Klavis service', - type: 'ConnectKlavisFailed', + message: error instanceof Error ? error.message : 'Failed to connect Composio service', + type: 'ConnectComposioFailed', }, success: false, }; @@ -309,91 +288,6 @@ class CredsExecutor extends BaseExecutor { }); }; - /** - * Open Klavis OAuth popup and poll for authorization completion - * Unlike Market OAuth which uses postMessage, Klavis OAuth uses polling - */ - private openKlavisOAuthAndWait = ( - oauthUrl: string, - identifier: string, - ): Promise<{ success: boolean }> => { - return new Promise((resolve) => { - const popup = window.open(oauthUrl, '_blank', 'width=600,height=700'); - - if (!popup) { - resolve({ success: false }); - return; - } - - let resolved = false; - // eslint-disable-next-line prefer-const - let pollInterval: ReturnType; - // eslint-disable-next-line prefer-const - let windowCheckInterval: ReturnType; - - const checkConnected = async (): Promise => { - try { - await useToolStore.getState().refreshKlavisServerTools(identifier); - const toolState = getToolStoreState(); - const server = klavisStoreSelectors.getServerByIdentifier(identifier)(toolState); - return server?.status === KlavisServerStatus.CONNECTED; - } catch { - return false; - } - }; - - const cleanup = () => { - if (resolved) return; - resolved = true; - clearInterval(pollInterval); - clearInterval(windowCheckInterval); - }; - - // Poll for authentication completion every 1s - pollInterval = setInterval(async () => { - if (resolved) return; - if (await checkConnected()) { - cleanup(); - resolve({ success: true }); - } - }, 1000); - - // Monitor popup closure — give a short grace period then treat as cancelled - windowCheckInterval = setInterval(() => { - if (popup.closed) { - clearInterval(windowCheckInterval); - if (resolved) return; - - // Grace period: check a few more times after popup closes (4s) - // User may have authorized right before closing - setTimeout(async () => { - if (resolved) return; - // One final check - if (await checkConnected()) { - cleanup(); - resolve({ success: true }); - } else { - cleanup(); - resolve({ success: false }); - } - }, 4000); - } - }, 500); - - // Hard timeout after 2 minutes - setTimeout( - () => { - if (!resolved) { - cleanup(); - if (!popup.closed) popup.close(); - resolve({ success: false }); - } - }, - 2 * 60 * 1000, - ); - }); - }; - /** * Inject credentials to sandbox environment * Calls the SDK inject API to get decrypted credentials for sandbox injection. diff --git a/packages/builtin-tool-creds/src/helpers.ts b/packages/builtin-tool-creds/src/helpers.ts index 4ce167b417a..d2003e40051 100644 --- a/packages/builtin-tool-creds/src/helpers.ts +++ b/packages/builtin-tool-creds/src/helpers.ts @@ -86,23 +86,23 @@ export const injectCredsContext = (content: string, context: UserCredsContext): .replaceAll('{{SETTINGS_URL}}', context.settingsUrl); }; -// ==================== Klavis Services ==================== +// ==================== Composio Services ==================== /** - * Summary of a Klavis service for display in the tool prompt + * Summary of a Composio service for display in the tool prompt */ -export interface KlavisServiceSummary { +export interface ComposioServiceSummary { description?: string; identifier: string; name: string; } /** - * Generate the Klavis services list string for injection into the prompt + * Generate the Composio services list string for injection into the prompt */ -export const generateKlavisServicesList = ( - connected: KlavisServiceSummary[], - available: KlavisServiceSummary[], +export const generateComposioServicesList = ( + connected: ComposioServiceSummary[], + available: ComposioServiceSummary[], ): string => { if (connected.length === 0 && available.length === 0) { return ''; @@ -114,20 +114,20 @@ export const generateKlavisServicesList = ( const items = connected .map( (s) => - ` - ${s.name} (identifier: ${s.identifier}) — Authorized via Klavis OAuth. Use ${s.identifier} tools directly.`, + ` - ${s.name} (identifier: ${s.identifier}) — Authorized via Composio OAuth. Use ${s.identifier} tools directly.`, ) .join('\n'); - sections.push(`**Connected Klavis Services (authorized, use tools directly):**\n${items}`); + sections.push(`**Connected Composio Services (authorized, use tools directly):**\n${items}`); } if (available.length > 0) { const items = available .map( (s) => - ` - ${s.name} (identifier: ${s.identifier}) — Use \`connectKlavisService\` to connect.`, + ` - ${s.name} (identifier: ${s.identifier}) — Use \`connectComposioService\` to connect.`, ) .join('\n'); - sections.push(`**Available Klavis Services (not yet connected):**\n${items}`); + sections.push(`**Available Composio Services (not yet connected):**\n${items}`); } return sections.join('\n\n'); diff --git a/packages/builtin-tool-creds/src/index.ts b/packages/builtin-tool-creds/src/index.ts index 863e8ca8171..56f107c04ce 100644 --- a/packages/builtin-tool-creds/src/index.ts +++ b/packages/builtin-tool-creds/src/index.ts @@ -1,20 +1,20 @@ export { CredsExecutionRuntime, type ICredsService } from './ExecutionRuntime'; export { checkCredsSatisfied, + type ComposioServiceSummary, type CredRequirement, type CredSummary, + generateComposioServicesList, generateCredsList, - generateKlavisServicesList, groupCredsByType, injectCredsContext, - type KlavisServiceSummary, type UserCredsContext, } from './helpers'; export { CredsIdentifier, CredsManifest } from './manifest'; export { systemPrompt } from './systemRole'; export { - type ConnectKlavisServiceParams, - type ConnectKlavisServiceState, + type ConnectComposioServiceParams, + type ConnectComposioServiceState, CredsApiName, type CredsApiNameType, type CredSummaryForContext, diff --git a/packages/builtin-tool-creds/src/manifest.ts b/packages/builtin-tool-creds/src/manifest.ts index 0293c84cb06..53df2ac4b29 100644 --- a/packages/builtin-tool-creds/src/manifest.ts +++ b/packages/builtin-tool-creds/src/manifest.ts @@ -10,14 +10,14 @@ export const CredsManifest: BuiltinToolManifest = { api: [ { description: - 'Connect a Klavis integration service via OAuth. Use this to authorize access to third-party services managed by the Klavis platform (e.g., Gmail, Google Calendar, Slack). Check the available Klavis services in the credentials context before calling this.', - name: CredsApiName.connectKlavisService, + 'Connect a Composio integration service via OAuth. Use this to authorize access to third-party services managed by the Composio platform (e.g., Gmail, Google Calendar, Slack). Check the available Composio services in the credentials context before calling this.', + name: CredsApiName.connectComposioService, parameters: { additionalProperties: false, properties: { service: { description: - 'The Klavis service identifier to connect (e.g., "gmail", "google-calendar"). See the available Klavis services list in the credentials context.', + 'The Composio service identifier to connect (e.g., "gmail", "google-calendar"). See the available Composio services list in the credentials context.', type: 'string', }, }, diff --git a/packages/builtin-tool-creds/src/systemRole.ts b/packages/builtin-tool-creds/src/systemRole.ts index 04cfb5507cb..b5d36adc4b1 100644 --- a/packages/builtin-tool-creds/src/systemRole.ts +++ b/packages/builtin-tool-creds/src/systemRole.ts @@ -93,17 +93,17 @@ When sandbox mode is enabled and you need to run code that requires credentials: - Use the file path directly in your code (e.g., \`GOOGLE_APPLICATION_CREDENTIALS=~/.creds/files/gcp-service-account/credentials.json\`) - -{{KLAVIS_SERVICES_LIST}} - - - -- **Klavis integrations** are OAuth connections managed by the Klavis platform for third-party services (e.g., Gmail, Google Calendar, Slack). -- For **connected** Klavis services: Use the corresponding tools directly. Do NOT ask users for API keys, tokens, or credentials — the authorization is already handled by Klavis. -- For **available but not connected** services: Use \`connectKlavisService\` to initiate the OAuth connection flow via Klavis. -- Klavis credentials **CANNOT** be injected via \`injectCredsToSandbox\` — they are tool-only authorizations managed externally by Klavis. -- If a user asks about a service that matches a connected Klavis integration, always prefer using the Klavis tools over asking the user for manual credentials. - + +{{COMPOSIO_SERVICES_LIST}} + + + +- **Composio integrations** are OAuth connections managed by the Composio platform for third-party services (e.g., Gmail, Google Calendar, Slack). +- For **connected** Composio services: Use the corresponding tools directly. Do NOT ask users for API keys, tokens, or credentials — the authorization is already handled by Composio. +- For **available but not connected** services: Use \`connectComposioService\` to initiate the OAuth connection flow via Composio. +- Composio credentials **CANNOT** be injected via \`injectCredsToSandbox\` — they are tool-only authorizations managed externally by Composio. +- If a user asks about a service that matches a connected Composio integration, always prefer using the Composio tools over asking the user for manual credentials. + - When credentials are relevant, mention which ones are available and how they can be used. diff --git a/packages/builtin-tool-creds/src/types.ts b/packages/builtin-tool-creds/src/types.ts index aa6bfeca3d3..4345b276538 100644 --- a/packages/builtin-tool-creds/src/types.ts +++ b/packages/builtin-tool-creds/src/types.ts @@ -2,10 +2,10 @@ import type { CredType } from '@lobechat/types'; export const CredsApiName = { /** - * Connect a Klavis integration service via OAuth - * Initiates Klavis OAuth flow for third-party services like Gmail, Google Calendar, etc. + * Connect a Composio integration service via OAuth + * Initiates Composio OAuth flow for third-party services like Gmail, Google Calendar, etc. */ - connectKlavisService: 'connectKlavisService', + connectComposioService: 'connectComposioService', /** * Initiate OAuth connection flow @@ -128,16 +128,16 @@ export interface SaveCredsState { success: boolean; } -// ==================== Klavis Service Types ==================== +// ==================== Composio Service Types ==================== -export interface ConnectKlavisServiceParams { +export interface ConnectComposioServiceParams { /** - * The Klavis service identifier to connect (e.g., 'gmail', 'google-calendar') + * The Composio service identifier to connect (e.g., 'gmail', 'google-calendar') */ service: string; } -export interface ConnectKlavisServiceState { +export interface ConnectComposioServiceState { /** * Whether the service is now connected */ @@ -147,9 +147,9 @@ export interface ConnectKlavisServiceState { */ identifier: string; /** - * OAuth URL (only present when authorization is needed) + * OAuth redirect URL (only present when authorization is needed) */ - oauthUrl?: string; + redirectUrl?: string; /** * The service display name */ diff --git a/packages/builtin-tool-group-agent-builder/src/manifest.ts b/packages/builtin-tool-group-agent-builder/src/manifest.ts index 725065bfb49..5349517c964 100644 --- a/packages/builtin-tool-group-agent-builder/src/manifest.ts +++ b/packages/builtin-tool-group-agent-builder/src/manifest.ts @@ -300,7 +300,7 @@ export const GroupAgentBuilderManifest: BuiltinToolManifest = { }, source: { description: - 'Plugin source type: "market" for MCP marketplace plugins, "official" for builtin/Klavis tools', + 'Plugin source type: "market" for MCP marketplace plugins, "official" for builtin/Composio tools', enum: ['market', 'official'], type: 'string', }, diff --git a/packages/builtin-tool-group-agent-builder/src/systemRole.ts b/packages/builtin-tool-group-agent-builder/src/systemRole.ts index 9a8098de783..cc794fef62a 100644 --- a/packages/builtin-tool-group-agent-builder/src/systemRole.ts +++ b/packages/builtin-tool-group-agent-builder/src/systemRole.ts @@ -14,7 +14,7 @@ The injected context includes: - **group_config**: systemPrompt (group-level shared content) - **group_members**: List of agents in the group with their names, avatars, and roles (including the supervisor agent) - **supervisor_agent**: The supervisor agent's configuration (model, provider, plugins, systemRole) -- **official_tools**: List of available official tools including built-in tools and Klavis integrations +- **official_tools**: List of available official tools including built-in tools and Composio integrations You should use this context to understand the current state of the group and its members before making any modifications. diff --git a/packages/const/package.json b/packages/const/package.json index b44e39a5889..3401e6bb0ca 100644 --- a/packages/const/package.json +++ b/packages/const/package.json @@ -21,7 +21,6 @@ }, "peerDependencies": { "@icons-pack/react-simple-icons": "^13.8.0", - "@lobehub/ui": "^5", - "klavis": "^2.15.0" + "@lobehub/ui": "^5" } } diff --git a/packages/const/src/klavis.ts b/packages/const/src/composio.ts similarity index 75% rename from packages/const/src/klavis.ts rename to packages/const/src/composio.ts index c9f964e4229..a5f73ab1d5e 100644 --- a/packages/const/src/klavis.ts +++ b/packages/const/src/composio.ts @@ -1,280 +1,263 @@ import type { IconType } from '@icons-pack/react-simple-icons'; import { SiCaldotcom } from '@icons-pack/react-simple-icons'; -import { Klavis } from 'klavis'; -export interface KlavisServerType { - /** - * Author/Developer of the integration - */ +export interface ComposioAppType { + appSlug: string; author: string; - /** - * Author's website URL - */ authorUrl?: string; description: string; icon: string | IconType; - /** - * Identifier used for storage in database (e.g., 'google-calendar') - * Format: lowercase, spaces replaced with hyphens - */ identifier: string; label: string; readme: string; - /** - * Server name used to call Klavis API (e.g., 'Google Calendar') - */ - serverName: Klavis.McpServerName; } -export const KLAVIS_SERVER_TYPES: KlavisServerType[] = [ +export const COMPOSIO_APP_TYPES: ComposioAppType[] = [ { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'GMAIL', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Gmail is a free email service provided by Google', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/gmail.svg', identifier: 'gmail', + label: 'Gmail', readme: 'Bring the power of Gmail directly into your AI assistant. Read, compose, and send emails, search your inbox, manage labels, and organize your communications—all through natural conversation.', - label: 'Gmail', - serverName: Klavis.McpServerName.Gmail, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'GOOGLECALENDAR', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Google Calendar is a time-management and scheduling calendar service', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googlecalendar.svg', identifier: 'google-calendar', + label: 'Google Calendar', readme: 'Integrate Google Calendar to view, create, and manage your events seamlessly. Schedule meetings, set reminders, check availability, and coordinate your time—all through natural language commands.', - label: 'Google Calendar', - serverName: Klavis.McpServerName.GoogleCalendar, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'AIRTABLE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Airtable is a cloud-based database and spreadsheet platform that combines the flexibility of a spreadsheet with the power of a database, enabling teams to organize, track, and collaborate on projects with customizable views and powerful automation features', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/airtable.svg', identifier: 'airtable', + label: 'Airtable', readme: 'Integrate with Airtable to manage your databases and workflows. Query records, create entries, update data, and automate operations with customizable views and powerful tracking features.', - label: 'Airtable', - serverName: Klavis.McpServerName.Airtable, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'GOOGLESHEETS', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Google Sheets is a web-based spreadsheet application that allows users to create, edit, and collaborate on spreadsheets online', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googlesheets.svg', identifier: 'google-sheets', + label: 'Google Sheets', readme: 'Connect to Google Sheets to read, write, and analyze spreadsheet data. Perform calculations, generate reports, create charts, and manage tabular data collaboratively with AI assistance.', - label: 'Google Sheets', - serverName: Klavis.McpServerName.GoogleSheets, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'GOOGLEDOCS', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Google Docs is a word processor included as part of the free, web-based Google Docs Editors suite', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googledocs.svg', identifier: 'google-docs', + label: 'Google Docs', readme: 'Integrate with Google Docs to create, edit, and manage documents. Write content, format text, collaborate in real-time, and access your documents through natural conversation.', - label: 'Google Docs', - serverName: Klavis.McpServerName.GoogleDocs, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', - description: 'Supabase official MCP Server', + appSlug: 'SUPABASE', + author: 'Composio', + authorUrl: 'https://composio.dev', + description: 'Supabase open source Firebase alternative with PostgreSQL', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/supabase.svg', identifier: 'supabase', + label: 'Supabase', readme: 'Integrate with Supabase to manage your database and backend services. Query data, manage authentication, handle storage, and interact with your application backend through natural conversation.', - label: 'Supabase', - serverName: Klavis.McpServerName.Supabase, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'GOOGLEDRIVE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Google Drive is a cloud storage service', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/googledrive.svg', identifier: 'google-drive', + label: 'Google Drive', readme: 'Connect to Google Drive to access, organize, and manage your files. Search documents, upload files, share content, and navigate your cloud storage efficiently through AI assistance.', - label: 'Google Drive', - serverName: Klavis.McpServerName.GoogleDrive, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'SLACK', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Slack is a messaging app for business that connects people to the information they need', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/slack.svg', identifier: 'slack', + label: 'Slack', readme: 'Integrate with Slack to send messages, search conversations, and manage channels. Connect with your team, automate communication workflows, and access workspace information through natural language.', - label: 'Slack', - serverName: Klavis.McpServerName.Slack, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'CONFLUENCE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Confluence is a team workspace where knowledge and collaboration meet', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/confluence.svg', identifier: 'confluence', + label: 'Confluence', readme: 'Connect to Confluence to access and manage team documentation. Search pages, create content, organize spaces, and build your knowledge base through conversational AI assistance.', - label: 'Confluence', - serverName: Klavis.McpServerName.Confluence, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'JIRA', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Jira is a project management and issue tracking tool developed by Atlassian', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/jira.svg', identifier: 'jira', + label: 'Jira', readme: 'Integrate with Jira to manage issues, track progress, and organize sprints. Create tickets, update statuses, query project data, and streamline your development workflow through natural conversation.', - label: 'Jira', - serverName: Klavis.McpServerName.Jira, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'CLICKUP', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'ClickUp is a comprehensive project management and productivity platform that helps teams organize tasks, manage projects, and collaborate effectively with customizable workflows and powerful tracking features', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/clickup.svg', identifier: 'clickup', + label: 'ClickUp', readme: 'Connect to ClickUp to manage tasks, track projects, and organize your work. Create tasks, update statuses, manage custom workflows, and collaborate with your team through natural language commands.', - label: 'ClickUp', - serverName: Klavis.McpServerName.Clickup, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'DROPBOX', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Complete file management solution for Dropbox cloud storage. Upload, download, organize files and folders, manage sharing and collaboration, handle file versions, create file requests, and perform batch operations on your Dropbox files and folders', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/dropbox.svg', identifier: 'dropbox', + label: 'Dropbox', readme: 'Integrate with Dropbox to access and manage your files. Upload, download, share files, manage folders, handle file versions, and organize your cloud storage through conversational AI.', - label: 'Dropbox', - serverName: Klavis.McpServerName.Dropbox, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'FIGMA', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Figma is a collaborative interface design tool for web and mobile applications.', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/figma.svg', identifier: 'figma', + label: 'Figma', readme: 'Connect to Figma to access design files and collaborate on projects. View designs, export assets, browse components, and manage your design workflow through natural conversation.', - label: 'Figma', - serverName: Klavis.McpServerName.Figma, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'HUBSPOT', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'HubSpot is a developer and marketer of software products for inbound marketing, sales, and customer service', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/hubspot.svg', identifier: 'hubspot', + label: 'HubSpot', readme: 'Integrate with HubSpot to manage contacts, deals, and marketing campaigns. Access CRM data, track pipelines, automate workflows, and streamline your sales and marketing operations.', - label: 'HubSpot', - serverName: Klavis.McpServerName.Hubspot, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'ONEDRIVE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'OneDrive is a file hosting service and synchronization service operated by Microsoft', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/onedrive.svg', identifier: 'onedrive', + label: 'OneDrive', readme: 'Connect to OneDrive to access and manage your Microsoft cloud files. Upload, download, share files, organize folders, and collaborate on documents through AI-powered assistance.', - label: 'OneDrive', - serverName: Klavis.McpServerName.Onedrive, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'OUTLOOK', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Outlook Mail is a web-based suite of webmail, contacts, tasks, and calendaring services from Microsoft.', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/outlook.svg', identifier: 'outlook-mail', + label: 'Outlook Mail', readme: 'Integrate with Outlook Mail to read, send, and manage your Microsoft emails. Search messages, compose emails, manage folders, and organize your inbox through natural conversation.', - label: 'Outlook Mail', - serverName: Klavis.McpServerName.OutlookMail, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'SALESFORCE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: "Salesforce is the world's leading customer relationship management (CRM) platform that helps businesses connect with customers, partners, and potential customers", icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/salesforce.svg', identifier: 'salesforce', + label: 'Salesforce', readme: 'Connect to Salesforce to manage customer relationships and sales data. Query records, update opportunities, track leads, and automate your CRM workflows through natural language commands.', - label: 'Salesforce', - serverName: Klavis.McpServerName.Salesforce, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'WHATSAPP', + author: 'Composio', + authorUrl: 'https://composio.dev', description: - 'WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers. Perfect for customer support, marketing campaigns, and automated messaging workflows through the official WhatsApp Business platform.', + 'WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers.', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/whatsapp.svg', identifier: 'whatsapp', + label: 'WhatsApp', readme: 'Integrate with WhatsApp Business to send messages, manage conversations, and engage with customers. Automate messaging workflows and handle communications through conversational AI.', - label: 'WhatsApp', - serverName: Klavis.McpServerName.Whatsapp, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'YOUTUBE', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'YouTube is a video-sharing platform where users can upload, share, and discover content. Access video information, transcripts, and metadata programmatically.', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/youtube.svg', identifier: 'youtube', + label: 'YouTube', readme: 'Connect to YouTube to search videos, access transcripts, and retrieve video information. Analyze content, extract metadata, and discover videos through natural conversation.', - label: 'YouTube', - serverName: Klavis.McpServerName.Youtube, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'ZENDESK', + author: 'Composio', + authorUrl: 'https://composio.dev', description: 'Zendesk is a customer service software company', icon: 'https://hub-apac-1.lobeobjects.space/assets/logos/zendesk.svg', identifier: 'zendesk', + label: 'Zendesk', readme: 'Integrate with Zendesk to manage support tickets and customer interactions. Create, update, and track support requests, access customer data, and streamline your support operations.', - label: 'Zendesk', - serverName: Klavis.McpServerName.Zendesk, }, { - author: 'Klavis', - authorUrl: 'https://klavis.io', + appSlug: 'CALCOM', + author: 'Composio', + authorUrl: 'https://composio.dev', description: - 'Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails. Manage event types, bookings, availability, and integrate with calendars for seamless appointment scheduling', + 'Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails.', icon: SiCaldotcom, identifier: 'cal-com', + label: 'Cal.com', readme: 'Connect to Cal.com to manage your scheduling and appointments. View availability, book meetings, manage event types, and automate your calendar through natural conversation.', - label: 'Cal.com', - serverName: Klavis.McpServerName.CalCom, }, ]; -/** - * Get server config by identifier - */ -export const getKlavisServerByServerIdentifier = (identifier: string) => - KLAVIS_SERVER_TYPES.find((s) => s.identifier === identifier); +export const getComposioAppByIdentifier = (identifier: string) => + COMPOSIO_APP_TYPES.find((s) => s.identifier === identifier); diff --git a/packages/const/src/index.ts b/packages/const/src/index.ts index f2520635bfb..1483f4b5b42 100644 --- a/packages/const/src/index.ts +++ b/packages/const/src/index.ts @@ -1,5 +1,6 @@ export * from './agentDocument'; export * from './bot'; +export * from './composio'; export * from './currency'; export * from './desktop'; export * from './desktopGlobalShortcuts'; @@ -9,7 +10,6 @@ export * from './empty'; export * from './fetch'; export * from './file'; export * from './interests'; -export * from './klavis'; export * from './layoutTokens'; export * from './llmGenerationTracing'; export * from './lobehubSkill'; diff --git a/packages/const/src/recommendedSkill.ts b/packages/const/src/recommendedSkill.ts index a80d9638bb3..c7d3eef2968 100644 --- a/packages/const/src/recommendedSkill.ts +++ b/packages/const/src/recommendedSkill.ts @@ -1,6 +1,6 @@ export enum RecommendedSkillType { Builtin = 'builtin', - Klavis = 'klavis', + Composio = 'composio', Lobehub = 'lobehub', } @@ -20,9 +20,9 @@ export const RECOMMENDED_SKILLS: RecommendedSkillItem[] = [ // LobeHub skills { id: 'notion', type: RecommendedSkillType.Lobehub }, { id: 'twitter', type: RecommendedSkillType.Lobehub }, - // Klavis skills - { id: 'gmail', type: RecommendedSkillType.Klavis }, - { id: 'google-drive', type: RecommendedSkillType.Klavis }, - { id: 'google-calendar', type: RecommendedSkillType.Klavis }, - { id: 'slack', type: RecommendedSkillType.Klavis }, + // Composio skills + { id: 'gmail', type: RecommendedSkillType.Composio }, + { id: 'google-drive', type: RecommendedSkillType.Composio }, + { id: 'google-calendar', type: RecommendedSkillType.Composio }, + { id: 'slack', type: RecommendedSkillType.Composio }, ]; diff --git a/packages/const/src/taskTemplate.test.ts b/packages/const/src/taskTemplate.test.ts index a205a120f53..172d2f2ec99 100644 --- a/packages/const/src/taskTemplate.test.ts +++ b/packages/const/src/taskTemplate.test.ts @@ -57,7 +57,7 @@ describe('taskTemplates', () => { for (const t of taskTemplates) { if (!t.optionalSkills) continue; for (const spec of t.optionalSkills) { - expect(['klavis', 'lobehub'], `template ${t.id} optional source`).toContain(spec.source); + expect(['composio', 'lobehub'], `template ${t.id} optional source`).toContain(spec.source); expect( spec.provider.length, `template ${t.id} optional provider "${spec.provider}"`, diff --git a/packages/const/src/taskTemplate.ts b/packages/const/src/taskTemplate.ts index bd0bbea1eea..f9b2fe70bfe 100644 --- a/packages/const/src/taskTemplate.ts +++ b/packages/const/src/taskTemplate.ts @@ -31,12 +31,12 @@ export interface TaskTemplate { } export interface TaskTemplateSkillRequirement { - /** Short identifier from `LOBEHUB_SKILL_PROVIDERS[i].id` or `KLAVIS_SERVER_TYPES[i].identifier`. */ + /** Short identifier from `LOBEHUB_SKILL_PROVIDERS[i].id` or `COMPOSIO_APP_TYPES[i].identifier`. */ provider: string; source: TaskTemplateSkillSource; } -export type TaskTemplateSkillSource = 'klavis' | 'lobehub'; +export type TaskTemplateSkillSource = 'composio' | 'lobehub'; export type TaskTemplateCategory = | 'content-creation' @@ -116,7 +116,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'content-creation', cronPattern: '0 9 * * 1', interests: ['writing', 'creator'], - requiresSkills: [{ provider: 'youtube', source: 'klavis' }], + requiresSkills: [{ provider: 'youtube', source: 'composio' }], }, { id: 'competitor-creator-tracking', @@ -199,7 +199,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'design', cronPattern: '0 17 * * 5', interests: ['design'], - requiresSkills: [{ provider: 'figma', source: 'klavis' }], + requiresSkills: [{ provider: 'figma', source: 'composio' }], }, { id: 'aigc-prompt-inspiration', @@ -309,21 +309,21 @@ export const taskTemplates: TaskTemplate[] = [ category: 'marketing', cronPattern: '0 10 * * 1', interests: ['marketing'], - requiresSkills: [{ provider: 'gmail', source: 'klavis' }], + requiresSkills: [{ provider: 'gmail', source: 'composio' }], }, { id: 'kol-collab-calendar', category: 'marketing', cronPattern: '0 9 * * 1', interests: ['marketing'], - requiresSkills: [{ provider: 'airtable', source: 'klavis' }], + requiresSkills: [{ provider: 'airtable', source: 'composio' }], }, { id: 'hubspot-funnel-daily', category: 'marketing', cronPattern: '0 9 * * *', interests: ['marketing', 'sales'], - requiresSkills: [{ provider: 'hubspot', source: 'klavis' }], + requiresSkills: [{ provider: 'hubspot', source: 'composio' }], }, // product @@ -364,7 +364,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'product', cronPattern: '0 9 * * 1', interests: ['product'], - requiresSkills: [{ provider: 'google-calendar', source: 'klavis' }], + requiresSkills: [{ provider: 'google-calendar', source: 'composio' }], }, { id: 'prd-review-reminder', @@ -380,21 +380,21 @@ export const taskTemplates: TaskTemplate[] = [ category: 'sales-customer', cronPattern: '0 9 * * *', interests: ['sales'], - requiresSkills: [{ provider: 'hubspot', source: 'klavis' }], + requiresSkills: [{ provider: 'hubspot', source: 'composio' }], }, { id: 'renewal-risk-weekly', category: 'sales-customer', cronPattern: '0 9 * * 1', interests: ['sales'], - requiresSkills: [{ provider: 'hubspot', source: 'klavis' }], + requiresSkills: [{ provider: 'hubspot', source: 'composio' }], }, { id: 'deal-pipeline-weekly', category: 'sales-customer', cronPattern: '0 16 * * 5', interests: ['sales'], - requiresSkills: [{ provider: 'hubspot', source: 'klavis' }], + requiresSkills: [{ provider: 'hubspot', source: 'composio' }], }, { id: 'key-account-radar', @@ -407,7 +407,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'sales-customer', cronPattern: '0 9 * * *', interests: ['sales'], - requiresSkills: [{ provider: 'zendesk', source: 'klavis' }], + requiresSkills: [{ provider: 'zendesk', source: 'composio' }], }, // operations @@ -416,21 +416,21 @@ export const taskTemplates: TaskTemplate[] = [ category: 'operations', cronPattern: '0 8 * * *', interests: ['operations'], - requiresSkills: [{ provider: 'google-calendar', source: 'klavis' }], + requiresSkills: [{ provider: 'google-calendar', source: 'composio' }], }, { id: 'meeting-brief', category: 'operations', cronPattern: '30 8 * * *', interests: ['operations'], - requiresSkills: [{ provider: 'google-calendar', source: 'klavis' }], + requiresSkills: [{ provider: 'google-calendar', source: 'composio' }], }, { id: 'calendar-conflict-check', category: 'operations', cronPattern: '30 7 * * *', interests: ['operations'], - requiresSkills: [{ provider: 'google-calendar', source: 'klavis' }], + requiresSkills: [{ provider: 'google-calendar', source: 'composio' }], }, { id: 'friday-wrap-list', @@ -446,7 +446,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'hr', cronPattern: '0 9 * * *', interests: ['hr'], - requiresSkills: [{ provider: 'airtable', source: 'klavis' }], + requiresSkills: [{ provider: 'airtable', source: 'composio' }], }, { id: 'onboarding-buddy-weekly', @@ -460,7 +460,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'hr', cronPattern: '0 9 * * 1', interests: ['hr'], - requiresSkills: [{ provider: 'google-calendar', source: 'klavis' }], + requiresSkills: [{ provider: 'google-calendar', source: 'composio' }], }, // finance-legal @@ -481,7 +481,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'finance-legal', cronPattern: '0 9 * * 1', interests: ['finance-legal'], - requiresSkills: [{ provider: 'airtable', source: 'klavis' }], + requiresSkills: [{ provider: 'airtable', source: 'composio' }], }, { id: 'contract-expiry-weekly', @@ -501,7 +501,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'finance-legal', cronPattern: '0 10 * * *', interests: ['finance-legal'], - requiresSkills: [{ provider: 'gmail', source: 'klavis' }], + requiresSkills: [{ provider: 'gmail', source: 'composio' }], }, // creator @@ -530,7 +530,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'creator', cronPattern: '0 9 * * 1', interests: ['creator'], - requiresSkills: [{ provider: 'youtube', source: 'klavis' }], + requiresSkills: [{ provider: 'youtube', source: 'composio' }], }, { id: 'monetization-opportunity-weekly', @@ -571,14 +571,14 @@ export const taskTemplates: TaskTemplate[] = [ category: 'parenting', cronPattern: '0 20 * * 0', interests: ['parenting', 'finance-legal'], - requiresSkills: [{ provider: 'google-sheets', source: 'klavis' }], + requiresSkills: [{ provider: 'google-sheets', source: 'composio' }], }, { id: 'family-task-schedule', category: 'parenting', cronPattern: '0 8 * * 1', interests: ['parenting'], - optionalSkills: [{ provider: 'google-calendar', source: 'klavis' }], + optionalSkills: [{ provider: 'google-calendar', source: 'composio' }], }, // health @@ -601,7 +601,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'hobbies', cronPattern: '0 20 * * 0', interests: ['hobbies'], - requiresSkills: [{ provider: 'gmail', source: 'klavis' }], + requiresSkills: [{ provider: 'gmail', source: 'composio' }], }, { id: 'series-update-weekly', @@ -646,7 +646,7 @@ export const taskTemplates: TaskTemplate[] = [ category: 'personal-life', cronPattern: '0 7 * * *', interests: ['personal'], - optionalSkills: [{ provider: 'google-calendar', source: 'klavis' }], + optionalSkills: [{ provider: 'google-calendar', source: 'composio' }], }, { id: 'bedtime-gratitude', diff --git a/packages/context-engine/src/engine/tools/ToolResolver.ts b/packages/context-engine/src/engine/tools/ToolResolver.ts index 3643097af71..4b6f48c6d24 100644 --- a/packages/context-engine/src/engine/tools/ToolResolver.ts +++ b/packages/context-engine/src/engine/tools/ToolResolver.ts @@ -102,7 +102,7 @@ export class ToolResolver { enabledToolIds.push(activation.id); // Only set source if not already present — the operation-level sourceMap - // may already have the correct routing source (e.g., 'lobehubSkill', 'klavis') + // may already have the correct routing source (e.g., 'lobehubSkill', 'composio') // and the activation source ('discovery') should not overwrite it. if (activation.source && !sourceMap[activation.id]) { sourceMap[activation.id] = this.mapSource(activation.source); diff --git a/packages/context-engine/src/engine/tools/types.ts b/packages/context-engine/src/engine/tools/types.ts index 52407f2cea6..5383a97e5b0 100644 --- a/packages/context-engine/src/engine/tools/types.ts +++ b/packages/context-engine/src/engine/tools/types.ts @@ -166,7 +166,7 @@ export interface UniformTool { // ---- Tool Lifecycle Types ---- -export type ToolSource = 'builtin' | 'client' | 'mcp' | 'klavis' | 'lobehubSkill'; +export type ToolSource = 'builtin' | 'client' | 'mcp' | 'composio' | 'lobehubSkill'; /** * Where the tool is executed for a given invocation. diff --git a/packages/context-engine/src/providers/AgentBuilderContextInjector.ts b/packages/context-engine/src/providers/AgentBuilderContextInjector.ts index 5f19906c8ce..5298db9dd2e 100644 --- a/packages/context-engine/src/providers/AgentBuilderContextInjector.ts +++ b/packages/context-engine/src/providers/AgentBuilderContextInjector.ts @@ -28,8 +28,8 @@ export interface OfficialToolItem { installed?: boolean; /** Tool display name */ name: string; - /** Tool type: 'builtin' for built-in tools, 'klavis' for LobeHub Mcp servers, 'lobehub-skill' for LobeHub Skill providers */ - type: 'builtin' | 'klavis' | 'lobehub-skill'; + /** Tool type: 'builtin' for built-in tools, 'composio' for LobeHub Mcp servers, 'lobehub-skill' for LobeHub Skill providers */ + type: 'builtin' | 'composio' | 'lobehub-skill'; } /** @@ -55,7 +55,7 @@ export interface AgentBuilderContext { tags?: string[]; title?: string; }; - /** Available official tools (builtin tools, Klavis integrations, and LobehubSkill providers) */ + /** Available official tools (builtin tools, Composio integrations, and LobehubSkill providers) */ officialTools?: OfficialToolItem[]; } @@ -132,7 +132,7 @@ const defaultFormatAgentContext = (context: AgentBuilderContext): string => { // Add official tools section if (context.officialTools && context.officialTools.length > 0) { const builtinTools = context.officialTools.filter((t) => t.type === 'builtin'); - const klavisTools = context.officialTools.filter((t) => t.type === 'klavis'); + const composioTools = context.officialTools.filter((t) => t.type === 'composio'); const lobehubSkillTools = context.officialTools.filter((t) => t.type === 'lobehub-skill'); const toolsSections: string[] = []; @@ -150,8 +150,8 @@ const defaultFormatAgentContext = (context: AgentBuilderContext): string => { toolsSections.push(` \n${builtinItems}\n `); } - if (klavisTools.length > 0) { - const klavisItems = klavisTools + if (composioTools.length > 0) { + const composioItems = composioTools .map((t) => { const attrs = [ `id="${t.identifier}"`, @@ -162,7 +162,7 @@ const defaultFormatAgentContext = (context: AgentBuilderContext): string => { return ` ${escapeXml(t.name)}${desc}`; }) .join('\n'); - toolsSections.push(` \n${klavisItems}\n `); + toolsSections.push(` \n${composioItems}\n `); } if (lobehubSkillTools.length > 0) { @@ -192,7 +192,7 @@ const defaultFormatAgentContext = (context: AgentBuilderContext): string => { } return ` -This is the current agent's configuration context. Use this information when the user asks about or wants to modify agent settings. Use togglePlugin to enable/disable tools, or installPlugin to install new tools (including builtin tools, Klavis servers, and LobehubSkill providers). +This is the current agent's configuration context. Use this information when the user asks about or wants to modify agent settings. Use togglePlugin to enable/disable tools, or installPlugin to install new tools (including builtin tools, Composio servers, and LobehubSkill providers). ${parts.join('\n')} `; }; diff --git a/packages/context-engine/src/providers/AgentManagementContextInjector.ts b/packages/context-engine/src/providers/AgentManagementContextInjector.ts index 9d416a44659..a71f59bd04c 100644 --- a/packages/context-engine/src/providers/AgentManagementContextInjector.ts +++ b/packages/context-engine/src/providers/AgentManagementContextInjector.ts @@ -67,11 +67,11 @@ export interface AvailablePluginInfo { /** Plugin display name */ name: string; /** - * Plugin source: 'builtin' for built-in tools, 'klavis' for Klavis servers, + * Plugin source: 'builtin' for built-in tools, 'composio' for Composio servers, * 'lobehub-skill' for LobehubSkill providers, 'custom' for user-added custom * MCP connectors (aligns with ConnectorSourceType.custom). */ - type: 'builtin' | 'klavis' | 'lobehub-skill' | 'custom'; + type: 'builtin' | 'composio' | 'lobehub-skill' | 'custom'; } /** @@ -167,7 +167,7 @@ const defaultFormatContext = (context: AgentManagementContext): string => { // Add available plugins section if (context.availablePlugins && context.availablePlugins.length > 0) { const builtinPlugins = context.availablePlugins.filter((p) => p.type === 'builtin'); - const klavisPlugins = context.availablePlugins.filter((p) => p.type === 'klavis'); + const composioPlugins = context.availablePlugins.filter((p) => p.type === 'composio'); const lobehubSkillPlugins = context.availablePlugins.filter((p) => p.type === 'lobehub-skill'); const customPlugins = context.availablePlugins.filter((p) => p.type === 'custom'); @@ -183,14 +183,14 @@ const defaultFormatContext = (context: AgentManagementContext): string => { pluginsSections.push(` \n${builtinItems}\n `); } - if (klavisPlugins.length > 0) { - const klavisItems = klavisPlugins + if (composioPlugins.length > 0) { + const composioItems = composioPlugins .map((p) => { const desc = p.description ? ` - ${escapeXml(p.description)}` : ''; return ` ${escapeXml(p.name)}${desc}`; }) .join('\n'); - pluginsSections.push(` \n${klavisItems}\n `); + pluginsSections.push(` \n${composioItems}\n `); } if (lobehubSkillPlugins.length > 0) { diff --git a/packages/context-engine/src/providers/GroupAgentBuilderContextInjector.ts b/packages/context-engine/src/providers/GroupAgentBuilderContextInjector.ts index aad1495a5c6..2986fa2f309 100644 --- a/packages/context-engine/src/providers/GroupAgentBuilderContextInjector.ts +++ b/packages/context-engine/src/providers/GroupAgentBuilderContextInjector.ts @@ -42,8 +42,8 @@ export interface GroupOfficialToolItem { installed?: boolean; /** Tool display name */ name: string; - /** Tool type: 'builtin' for built-in tools, 'klavis' for LobeHub Mcp servers, 'lobehub-skill' for LobeHub Skill providers */ - type: 'builtin' | 'klavis' | 'lobehub-skill'; + /** Tool type: 'builtin' for built-in tools, 'composio' for LobeHub Mcp servers, 'lobehub-skill' for LobeHub Skill providers */ + type: 'builtin' | 'composio' | 'lobehub-skill'; } /** @@ -69,7 +69,7 @@ export interface GroupAgentBuilderContext { groupTitle?: string; /** Group members */ members?: GroupMemberItem[]; - /** Available official tools (builtin tools and Klavis integrations) */ + /** Available official tools (builtin tools and Composio integrations) */ officialTools?: GroupOfficialToolItem[]; /** Supervisor agent configuration */ supervisorConfig?: { @@ -189,7 +189,7 @@ const defaultFormatGroupContext = (context: GroupAgentBuilderContext): string => // Add official tools section if (context.officialTools && context.officialTools.length > 0) { const builtinTools = context.officialTools.filter((t) => t.type === 'builtin'); - const klavisTools = context.officialTools.filter((t) => t.type === 'klavis'); + const composioTools = context.officialTools.filter((t) => t.type === 'composio'); const lobehubSkillTools = context.officialTools.filter((t) => t.type === 'lobehub-skill'); const toolsSections: string[] = []; @@ -207,8 +207,8 @@ const defaultFormatGroupContext = (context: GroupAgentBuilderContext): string => toolsSections.push(` \n${builtinItems}\n `); } - if (klavisTools.length > 0) { - const klavisItems = klavisTools + if (composioTools.length > 0) { + const composioItems = composioTools .map((t) => { const attrs = [ `id="${t.identifier}"`, @@ -219,7 +219,7 @@ const defaultFormatGroupContext = (context: GroupAgentBuilderContext): string => return ` ${escapeXml(t.name)}${desc}`; }) .join('\n'); - toolsSections.push(` \n${klavisItems}\n `); + toolsSections.push(` \n${composioItems}\n `); } if (lobehubSkillTools.length > 0) { diff --git a/packages/database/src/models/__tests__/topics/topic.create.test.ts b/packages/database/src/models/__tests__/topics/topic.create.test.ts index 91c56c588c7..f0842dbfd3f 100644 --- a/packages/database/src/models/__tests__/topics/topic.create.test.ts +++ b/packages/database/src/models/__tests__/topics/topic.create.test.ts @@ -392,9 +392,26 @@ describe('TopicModel - Create', () => { await serverDB.transaction(async (tx) => { await tx.insert(topics).values({ id: topicId, sessionId, userId, title: 'Original Topic' }); + // Distinct createdAt so `duplicate`'s `orderBy(createdAt)` is + // deterministic — inserting both in one tx would otherwise give them the + // same `now()` default, leaving the tied rows in arbitrary order. await tx.insert(messages).values([ - { id: 'message1', role: 'user', topicId, userId, content: 'User message' }, - { id: 'message2', role: 'assistant', topicId, userId, content: 'Assistant message' }, + { + id: 'message1', + role: 'user', + topicId, + userId, + content: 'User message', + createdAt: new Date('2024-01-01T00:00:00Z'), + }, + { + id: 'message2', + role: 'assistant', + topicId, + userId, + content: 'Assistant message', + createdAt: new Date('2024-01-01T00:00:01Z'), + }, ]); }); diff --git a/packages/database/src/models/connectorTool.ts b/packages/database/src/models/connectorTool.ts index fd124652589..f9159828b81 100644 --- a/packages/database/src/models/connectorTool.ts +++ b/packages/database/src/models/connectorTool.ts @@ -134,7 +134,7 @@ export class ConnectorToolModel { /** * Look up a single tool by its toolName for this user. - * Used for direct permission checks (e.g. Klavis gate). + * Used for direct permission checks (e.g. Composio gate). */ findByToolName = async (toolName: string): Promise => { const results = await this.db diff --git a/packages/heterogeneous-agents/src/subagentCoordinator/reducer.test.ts b/packages/heterogeneous-agents/src/subagentCoordinator/reducer.test.ts index aaa7296517f..81205aeccd4 100644 --- a/packages/heterogeneous-agents/src/subagentCoordinator/reducer.test.ts +++ b/packages/heterogeneous-agents/src/subagentCoordinator/reducer.test.ts @@ -236,6 +236,24 @@ describe('subagent reducer', () => { expect(state.runs.has('task-1')).toBe(false); // deleted }); + it('does NOT re-create the thread when a finalized spawn replays its first event', () => { + // Finalize via the parent tool_result, then replay the SAME first chunk a + // cold-replica retry / double IPC delivery would resend. `ensureRun` must + // treat the already-finalized parent as a stale no-op — no second thread. + const { steps, state } = run([ + textEvent('task-1', 'm1', 'working', { description: 'Map client runtime' }), + { data: { content: 'answer', toolCallId: 'task-1' }, type: 'tool_result' }, // finalize + // ↓ exact replay of the very first subagent chunk for task-1 + textEvent('task-1', 'm1', 'working', { description: 'Map client runtime' }), + ]); + + // The replay produces NO intents (no createThread, no createMessage). + expect(steps[2]).toEqual([]); + // Run stays deleted; the parent is remembered as finalized. + expect(state.runs.has('task-1')).toBe(false); + expect(state.finalizedParents.has('task-1')).toBe(true); + }); + it('records subagent usage onto the current assistant', () => { const usage = { totalTokens: 42 }; const { steps } = run([ diff --git a/packages/heterogeneous-agents/src/subagentCoordinator/reducer.ts b/packages/heterogeneous-agents/src/subagentCoordinator/reducer.ts index 88c39f4d594..4aa953c594d 100644 --- a/packages/heterogeneous-agents/src/subagentCoordinator/reducer.ts +++ b/packages/heterogeneous-agents/src/subagentCoordinator/reducer.ts @@ -60,13 +60,25 @@ const withRun = ( ): SubagentRunsState => { const runs = new Map(state.runs); runs.set(parentToolCallId, run); - return { runs }; + return { ...state, runs }; }; -const withoutRun = (state: SubagentRunsState, parentToolCallId: string): SubagentRunsState => { +/** + * Finalize bookkeeping: drop the live run AND remember its `parentToolCallId` in + * `finalizedParents` so a replayed first-event never re-creates the (now + * `Active`) thread. The remembered set is what makes thread creation idempotent + * across cold-replica retries / double IPC delivery — keyed by the DB-homed + * `sourceToolCallId`, independent of whether the live `runs` map still holds it. + */ +const markRunFinalized = ( + state: SubagentRunsState, + parentToolCallId: string, +): SubagentRunsState => { const runs = new Map(state.runs); runs.delete(parentToolCallId); - return { runs }; + const finalizedParents = new Set(state.finalizedParents); + finalizedParents.add(parentToolCallId); + return { ...state, finalizedParents, runs }; }; const SUBAGENT_TITLE_MAX = 80; @@ -82,15 +94,24 @@ interface ReduceResult { * run, the next state, and any structural intents (thread + message creates, * prior-turn flush). The returned `run` is a fresh copy safe to mutate further * by the caller before it calls `withRun` to fold it back into state. + * + * Returns `run: null` when the parent already FINALIZED (its thread is `Active`, + * tracked in `finalizedParents`): the event is a stale replay of a completed + * spawn — re-creating its thread would duplicate it. The caller drops the event. */ const ensureRun = ( state: SubagentRunsState, subCtx: SubagentEventContext, ctx: SubagentReduceCtx, -): { intents: SubagentIntent[]; run: SubagentRun; state: SubagentRunsState } => { +): { intents: SubagentIntent[]; run: SubagentRun | null; state: SubagentRunsState } => { const intents: SubagentIntent[] = []; const existing = state.runs.get(subCtx.parentToolCallId); + // ─── Stale replay of an already-finalized spawn → no-op (no duplicate thread) ─── + if (!existing && state.finalizedParents.has(subCtx.parentToolCallId)) { + return { intents, run: null, state }; + } + // ─── First event for this parent → lazy-create Thread + seed + assistant ─── if (!existing) { const threadId = ctx.newId('thread'); @@ -235,7 +256,7 @@ const finalizeRun = ( intents.push({ kind: 'finalizeThread', threadId: run.threadId }); - return { intents, state: withoutRun(state, parentToolCallId) }; + return { intents, state: markRunFinalized(state, parentToolCallId) }; }; /** Find the run that owns an inner tool_call id (lifetime lookup). */ @@ -259,6 +280,8 @@ const reduceTextChunk = ( const ensured = ensureRun(state, subCtx, ctx); const run = ensured.run; const intents = ensured.intents; + // Stale replay of a finalized spawn — drop without re-creating its thread. + if (!run) return { intents, state: ensured.state }; if (kind === 'text') run.accContent += chunk; else run.accReasoning += chunk; @@ -282,6 +305,8 @@ const reduceToolsChunk = ( const ensured = ensureRun(state, subCtx, ctx); const run = ensured.run; const intents = ensured.intents; + // Stale replay of a finalized spawn — drop without re-creating its thread. + if (!run) return { intents, state: ensured.state }; const newToolMsgIds: string[] = []; for (const tool of tools) { diff --git a/packages/heterogeneous-agents/src/subagentCoordinator/types.ts b/packages/heterogeneous-agents/src/subagentCoordinator/types.ts index 06411babb9c..941af9911cd 100644 --- a/packages/heterogeneous-agents/src/subagentCoordinator/types.ts +++ b/packages/heterogeneous-agents/src/subagentCoordinator/types.ts @@ -71,11 +71,23 @@ export interface SubagentRun { } export interface SubagentRunsState { + /** + * `parentToolCallId`s whose subagent already FINALIZED (thread is `Active`). + * The run itself is deleted from `runs` on finalize, but the parent is + * remembered here so a REPLAYED first-event (cold-replica retry, double IPC + * delivery) does NOT fork a brand-new duplicate thread for a spawn that is + * already done. Distinct from `runs` on purpose: finalized spawns must block + * re-creation WITHOUT being resurrected into the live turn machinery (which + * would mint spurious empty assistants / re-finalize churn). Survives turn + * boundaries; on the server it is reseeded from DB `Active` isolation threads. + */ + finalizedParents: Set; /** Active subagent runs, keyed by `parentToolCallId`. */ runs: Map; } export const createSubagentRunsState = (): SubagentRunsState => ({ + finalizedParents: new Set(), runs: new Map(), }); @@ -124,8 +136,16 @@ export interface SubagentRunSnapshot { * instead of forking a new one. `accContent` / `accReasoning` / per-turn * `toolState` start empty — the next turn boundary opens a fresh in-thread * assistant, and inner tool_results still resolve through `lifetimeToolCallIds`. + * + * `finalizedParentToolCallIds` seeds {@link SubagentRunsState.finalizedParents} + * — `parentToolCallId`s whose thread already finalized (`Active`). These are NOT + * live runs (a completed spawn is never resurrected); they only block a replayed + * first-event from forking a duplicate thread on a cold replica. */ -export const rehydrateSubagentRunsState = (snapshots: SubagentRunSnapshot[]): SubagentRunsState => { +export const rehydrateSubagentRunsState = ( + snapshots: SubagentRunSnapshot[], + finalizedParentToolCallIds: string[] = [], +): SubagentRunsState => { const runs = new Map(); for (const s of snapshots) { runs.set(s.parentToolCallId, { @@ -139,7 +159,7 @@ export const rehydrateSubagentRunsState = (snapshots: SubagentRunSnapshot[]): Su toolState: { payloads: [], persistedIds: new Set(), toolMsgIdByCallId: new Map() }, }); } - return { runs }; + return { finalizedParents: new Set(finalizedParentToolCallIds), runs }; }; // ─── Reduce context (per event) ─── diff --git a/packages/locales/src/default/setting.ts b/packages/locales/src/default/setting.ts index 9ea00e06a92..fd8d9708f73 100644 --- a/packages/locales/src/default/setting.ts +++ b/packages/locales/src/default/setting.ts @@ -2320,168 +2320,169 @@ When I am ___, I need ___ 'tools.builtins.uninstallConfirm.title': 'Uninstall {{name}}', 'tools.builtins.uninstalled': 'Uninstalled', 'tools.disabled': 'The current model does not support function calls and cannot use the skill', - 'tools.klavis.addServer': 'Add Server', - 'tools.klavis.authCompleted': 'Authentication Completed', - 'tools.klavis.authFailed': 'Authentication Failed', - 'tools.klavis.authRequired': 'Authentication Required', - 'tools.klavis.connect': 'Connect', - 'tools.klavis.connected': 'Connected', - 'tools.klavis.disconnect': 'Disconnect', - 'tools.klavis.disconnected': 'Disconnected', - 'tools.klavis.error': 'Error', - 'tools.klavis.remove': 'Remove', - 'tools.klavis.removeConfirm.desc': + 'tools.composio.addServer': 'Add Server', + 'tools.composio.authCompleted': 'Authentication Completed', + 'tools.composio.authFailed': 'Authentication Failed', + 'tools.composio.authRequired': 'Authentication Required', + 'tools.composio.connect': 'Connect', + 'tools.composio.connected': 'Connected', + 'tools.composio.disconnect': 'Disconnect', + 'tools.composio.disconnected': 'Disconnected', + 'tools.composio.error': 'Error', + 'tools.composio.remove': 'Remove', + 'tools.composio.removeConfirm.desc': '{{name}} will be permanently removed from your connected services. This action cannot be undone.', - 'tools.klavis.removeConfirm.title': 'Remove {{name}}?', - 'tools.klavis.groupName': 'Klavis Tools', - 'tools.klavis.manage': 'Manage Klavis', - 'tools.klavis.manageTitle': 'Manage Klavis Integration', - 'tools.klavis.noServers': 'No connected servers', - 'tools.klavis.notEnabled': 'Klavis service not enabled', - 'tools.klavis.oauthRequired': 'Please complete OAuth authentication in the new window', - 'tools.klavis.pendingAuth': 'Pending Authentication', - 'tools.klavis.serverCreated': 'Server created successfully', - 'tools.klavis.serverCreatedFailed': 'Failed to create server', - 'tools.klavis.serverRemoved': 'Server removed', - 'tools.klavis.servers': 'servers', - - 'tools.klavis.servers.airtable.description': + 'tools.composio.removeConfirm.title': 'Remove {{name}}?', + 'tools.composio.groupName': 'Composio Tools', + 'tools.composio.manage': 'Manage Composio', + 'tools.composio.manageTitle': 'Manage Composio Integration', + 'tools.composio.noServers': 'No connected servers', + 'tools.composio.notEnabled': 'Composio service not enabled', + 'tools.composio.oauthRequired': 'Please complete OAuth authentication in the new window', + 'tools.composio.pendingAuth': 'Pending Authentication', + 'tools.composio.reauthorize': 'Re-authorize', + 'tools.composio.serverCreated': 'Server created successfully', + 'tools.composio.serverCreatedFailed': 'Failed to create server', + 'tools.composio.serverRemoved': 'Server removed', + 'tools.composio.servers': 'servers', + + 'tools.composio.servers.airtable.description': 'Airtable is a cloud-based database and spreadsheet platform that combines the flexibility of a spreadsheet with the power of a database, enabling teams to organize, track, and collaborate on projects with customizable views and powerful automation features', - 'tools.klavis.servers.airtable.readme': + 'tools.composio.servers.airtable.readme': 'Integrate with Airtable to manage your databases and workflows. Query records, create entries, update data, and automate operations with customizable views and powerful tracking features.', - 'tools.klavis.servers.cal-com.description': + 'tools.composio.servers.cal-com.description': 'Cal.com is an open-source scheduling platform that helps you schedule meetings without the back-and-forth emails. Manage event types, bookings, availability, and integrate with calendars for seamless appointment scheduling', - 'tools.klavis.servers.cal-com.readme': + 'tools.composio.servers.cal-com.readme': 'Connect to Cal.com to manage your scheduling and appointments. View availability, book meetings, manage event types, and automate your calendar through natural conversation.', - 'tools.klavis.servers.clickup.description': + 'tools.composio.servers.clickup.description': 'ClickUp is a comprehensive project management and productivity platform that helps teams organize tasks, manage projects, and collaborate effectively with customizable workflows and powerful tracking features', - 'tools.klavis.servers.clickup.readme': + 'tools.composio.servers.clickup.readme': 'Connect to ClickUp to manage tasks, track projects, and organize your work. Create tasks, update statuses, manage custom workflows, and collaborate with your team through natural language commands.', - 'tools.klavis.servers.confluence.description': + 'tools.composio.servers.confluence.description': 'Confluence is a team workspace where knowledge and collaboration meet', - 'tools.klavis.servers.confluence.readme': + 'tools.composio.servers.confluence.readme': 'Connect to Confluence to access and manage team documentation. Search pages, create content, organize spaces, and build your knowledge base through conversational AI assistance.', - 'tools.klavis.servers.dropbox.description': + 'tools.composio.servers.dropbox.description': 'Complete file management solution for Dropbox cloud storage. Upload, download, organize files and folders, manage sharing and collaboration, handle file versions, create file requests, and perform batch operations on your Dropbox files and folders', - 'tools.klavis.servers.dropbox.readme': + 'tools.composio.servers.dropbox.readme': 'Integrate with Dropbox to access and manage your files. Upload, download, share files, manage folders, handle file versions, and organize your cloud storage through conversational AI.', - 'tools.klavis.servers.figma.description': + 'tools.composio.servers.figma.description': 'Figma is a collaborative interface design tool for web and mobile applications.', - 'tools.klavis.servers.figma.readme': + 'tools.composio.servers.figma.readme': 'Connect to Figma to access design files and collaborate on projects. View designs, export assets, browse components, and manage your design workflow through natural conversation.', - 'tools.klavis.servers.github.description': 'Enhanced GitHub MCP Server', + 'tools.composio.servers.github.description': 'Enhanced GitHub MCP Server', - 'tools.klavis.servers.github.readme': + 'tools.composio.servers.github.readme': 'Connect to GitHub to manage repositories, issues, pull requests, and code. Search code, review changes, create branches, and collaborate on software development projects through conversational AI.', - // Klavis Servers i18n - 'tools.klavis.servers.gmail.description': 'Gmail is a free email service provided by Google', + // Composio Servers i18n + 'tools.composio.servers.gmail.description': 'Gmail is a free email service provided by Google', - 'tools.klavis.servers.gmail.readme': + 'tools.composio.servers.gmail.readme': 'Bring the power of Gmail directly into your AI assistant. Read, compose, and send emails, search your inbox, manage labels, and organize your communications—all through natural conversation.', - 'tools.klavis.servers.google-calendar.description': + 'tools.composio.servers.google-calendar.description': 'Google Calendar is a time-management and scheduling calendar service', - 'tools.klavis.servers.google-calendar.readme': + 'tools.composio.servers.google-calendar.readme': 'Integrate Google Calendar to view, create, and manage your events seamlessly. Schedule meetings, set reminders, check availability, and coordinate your time—all through natural language commands.', - 'tools.klavis.servers.google-docs.description': + 'tools.composio.servers.google-docs.description': 'Google Docs is a word processor included as part of the free, web-based Google Docs Editors suite', - 'tools.klavis.servers.google-docs.readme': + 'tools.composio.servers.google-docs.readme': 'Integrate with Google Docs to create, edit, and manage documents. Write content, format text, collaborate in real-time, and access your documents through natural conversation.', - 'tools.klavis.servers.google-drive.description': 'Google Drive is a cloud storage service', + 'tools.composio.servers.google-drive.description': 'Google Drive is a cloud storage service', - 'tools.klavis.servers.google-drive.readme': + 'tools.composio.servers.google-drive.readme': 'Connect to Google Drive to access, organize, and manage your files. Search documents, upload files, share content, and navigate your cloud storage efficiently through AI assistance.', - 'tools.klavis.servers.google-sheets.description': + 'tools.composio.servers.google-sheets.description': 'Google Sheets is a web-based spreadsheet application that allows users to create, edit, and collaborate on spreadsheets online', - 'tools.klavis.servers.google-sheets.readme': + 'tools.composio.servers.google-sheets.readme': 'Connect to Google Sheets to read, write, and analyze spreadsheet data. Perform calculations, generate reports, create charts, and manage tabular data collaboratively with AI assistance.', - 'tools.klavis.servers.hubspot.description': + 'tools.composio.servers.hubspot.description': 'HubSpot is a developer and marketer of software products for inbound marketing, sales, and customer service', - 'tools.klavis.servers.hubspot.readme': + 'tools.composio.servers.hubspot.readme': 'Integrate with HubSpot to manage contacts, deals, and marketing campaigns. Access CRM data, track pipelines, automate workflows, and streamline your sales and marketing operations.', - 'tools.klavis.servers.jira.description': + 'tools.composio.servers.jira.description': 'Jira is a project management and issue tracking tool developed by Atlassian', - 'tools.klavis.servers.jira.readme': + 'tools.composio.servers.jira.readme': 'Integrate with Jira to manage issues, track progress, and organize sprints. Create tickets, update statuses, query project data, and streamline your development workflow through natural conversation.', - 'tools.klavis.servers.notion.description': + 'tools.composio.servers.notion.description': 'Notion is a collaborative productivity and note-taking application', - 'tools.klavis.servers.notion.readme': + 'tools.composio.servers.notion.readme': 'Connect to Notion to access and manage your workspace. Create pages, search content, update databases, and organize your knowledge base—all through natural conversation with your AI assistant.', - 'tools.klavis.servers.onedrive.description': + 'tools.composio.servers.onedrive.description': 'OneDrive is a file hosting service and synchronization service operated by Microsoft', - 'tools.klavis.servers.onedrive.readme': + 'tools.composio.servers.onedrive.readme': 'Connect to OneDrive to access and manage your Microsoft cloud files. Upload, download, share files, organize folders, and collaborate on documents through AI-powered assistance.', - 'tools.klavis.servers.outlook-mail.description': + 'tools.composio.servers.outlook-mail.description': 'Outlook Mail is a web-based suite of webmail, contacts, tasks, and calendaring services from Microsoft.', - 'tools.klavis.servers.outlook-mail.readme': + 'tools.composio.servers.outlook-mail.readme': 'Integrate with Outlook Mail to read, send, and manage your Microsoft emails. Search messages, compose emails, manage folders, and organize your inbox through natural conversation.', - 'tools.klavis.servers.salesforce.description': + 'tools.composio.servers.salesforce.description': "Salesforce is the world's leading customer relationship management (CRM) platform that helps businesses connect with customers, partners, and potential customers", - 'tools.klavis.servers.salesforce.readme': + 'tools.composio.servers.salesforce.readme': 'Connect to Salesforce to manage customer relationships and sales data. Query records, update opportunities, track leads, and automate your CRM workflows through natural language commands.', - 'tools.klavis.servers.slack.description': + 'tools.composio.servers.slack.description': 'Slack is a messaging app for business that connects people to the information they need', - 'tools.klavis.servers.slack.readme': + 'tools.composio.servers.slack.readme': 'Integrate with Slack to send messages, search conversations, and manage channels. Connect with your team, automate communication workflows, and access workspace information through natural language.', - 'tools.klavis.servers.supabase.description': 'Supabase official MCP Server', + 'tools.composio.servers.supabase.description': 'Supabase official MCP Server', - 'tools.klavis.servers.supabase.readme': + 'tools.composio.servers.supabase.readme': 'Integrate with Supabase to manage your database and backend services. Query data, manage authentication, handle storage, and interact with your application backend through natural conversation.', - 'tools.klavis.servers.whatsapp.description': + 'tools.composio.servers.whatsapp.description': 'WhatsApp Business API integration that enables sending text messages, media, and managing conversations with customers. Perfect for customer support, marketing campaigns, and automated messaging workflows through the official WhatsApp Business platform.', - 'tools.klavis.servers.whatsapp.readme': + 'tools.composio.servers.whatsapp.readme': 'Integrate with WhatsApp Business to send messages, manage conversations, and engage with customers. Automate messaging workflows and handle communications through conversational AI.', - 'tools.klavis.servers.youtube.description': + 'tools.composio.servers.youtube.description': 'YouTube is a video-sharing platform where users can upload, share, and discover content. Access video information, transcripts, and metadata programmatically.', - 'tools.klavis.servers.youtube.readme': + 'tools.composio.servers.youtube.readme': 'Connect to YouTube to search videos, access transcripts, and retrieve video information. Analyze content, extract metadata, and discover videos through natural conversation.', - 'tools.klavis.servers.zendesk.description': 'Zendesk is a customer service software company', + 'tools.composio.servers.zendesk.description': 'Zendesk is a customer service software company', - 'tools.klavis.servers.zendesk.readme': + 'tools.composio.servers.zendesk.readme': 'Integrate with Zendesk to manage support tickets and customer interactions. Create, update, and track support requests, access customer data, and streamline your support operations.', - 'tools.klavis.tools': 'tools', + 'tools.composio.tools': 'tools', - 'tools.klavis.verifyAuth': 'I have completed authentication', + 'tools.composio.verifyAuth': 'I have completed authentication', 'tools.lobehubSkill.authorize': 'Authorize', diff --git a/packages/observability-otel/src/modules/agent-runtime/index.ts b/packages/observability-otel/src/modules/agent-runtime/index.ts index 43c39eff78f..3f2bbc7885c 100644 --- a/packages/observability-otel/src/modules/agent-runtime/index.ts +++ b/packages/observability-otel/src/modules/agent-runtime/index.ts @@ -1,4 +1,6 @@ -import { trace } from '@opentelemetry/api'; +import { metrics, trace } from '@opentelemetry/api'; + +const meter = metrics.getMeter('server-services-agent-runtime'); /** * Tracer for Agent Runtime semantic spans (invoke_agent / chat / execute_tool / @@ -10,5 +12,23 @@ import { trace } from '@opentelemetry/api'; */ export const tracer = trace.getTracer('@lobechat/agent-runtime', '0.0.1'); +/** + * Count of async sub-agent parent resume attempts grouped by `outcome`: + * - `resumed` — won the resume CAS and scheduled the parent's next step + * - `barrier_held` — pending tools not all fulfilled yet, re-check armed + * - `no_pending` — parked op had no pending tools (snapshot lag), fallback armed + * - `no_state` — parent state missing/expired in Redis, cannot resume + * - `lost_cas` — another completion won the resume CAS first + * - `verify_exhausted`— bounded watchdog retries exhausted while still not resumable + * + * Lets orphaned `waiting_for_async_tool` parents be detected via the + * `barrier_held` / `no_pending` / `verify_exhausted` series instead of + * accumulating silently. See LOBE-10385. + */ +export const asyncToolResumeCounter = meter.createCounter('agent_runtime_async_tool_resume_total', { + description: 'Count of async sub-agent parent resume attempts grouped by outcome.', + unit: '{resume}', +}); + export * from './attributes'; export * from './semconv'; diff --git a/packages/observability-otel/src/modules/agent-runtime/semconv.ts b/packages/observability-otel/src/modules/agent-runtime/semconv.ts index a8fcab77d7a..5e4572e56cb 100644 --- a/packages/observability-otel/src/modules/agent-runtime/semconv.ts +++ b/packages/observability-otel/src/modules/agent-runtime/semconv.ts @@ -83,7 +83,7 @@ export const ATTR_LOBEHUB_TOOL_SUCCESS = 'lobehub.tool.success' as const; /** Attempts taken to execute a tool (1 for first-try success). */ export const ATTR_LOBEHUB_TOOL_ATTEMPTS = 'lobehub.tool.attempts' as const; -/** Internal LobeHub tool source (`builtin` / `client` / `mcp` / `klavis` / `lobehubSkill`). */ +/** Internal LobeHub tool source (`builtin` / `client` / `mcp` / `composio` / `lobehubSkill`). */ export const ATTR_LOBEHUB_TOOL_SOURCE = 'lobehub.tool.source' as const; /** Context engineering metadata. */ diff --git a/packages/prompts/src/prompts/agentBuilder/toolsResultsPrompt.ts b/packages/prompts/src/prompts/agentBuilder/toolsResultsPrompt.ts index 0ca0d789325..6f2c9027834 100644 --- a/packages/prompts/src/prompts/agentBuilder/toolsResultsPrompt.ts +++ b/packages/prompts/src/prompts/agentBuilder/toolsResultsPrompt.ts @@ -17,7 +17,7 @@ export interface OfficialToolResultItem { installed?: boolean; name: string; status?: 'connected' | 'error' | 'pending_auth'; - type: 'builtin' | 'klavis'; + type: 'builtin' | 'composio'; } /** diff --git a/packages/types/src/message/common/tools.ts b/packages/types/src/message/common/tools.ts index d6b647c1d25..0fb61e2c85b 100644 --- a/packages/types/src/message/common/tools.ts +++ b/packages/types/src/message/common/tools.ts @@ -25,7 +25,7 @@ export interface ChatPluginPayload { /** * Tool source indicates where the tool comes from */ -export type ToolSource = 'builtin' | 'client' | 'mcp' | 'klavis' | 'lobehubSkill'; +export type ToolSource = 'builtin' | 'client' | 'mcp' | 'composio' | 'lobehubSkill'; /** * Tool executor indicates where the tool is executed for a given invocation. diff --git a/packages/types/src/serverConfig.ts b/packages/types/src/serverConfig.ts index 696e0af1baa..8d3416e7cdf 100644 --- a/packages/types/src/serverConfig.ts +++ b/packages/types/src/serverConfig.ts @@ -62,6 +62,7 @@ export interface GlobalServerConfig { defaultAgent?: PartialDeep; disableEmailPassword?: boolean; enableBusinessFeatures?: boolean; + enableComposio?: boolean; /** * @deprecated */ @@ -71,7 +72,6 @@ export interface GlobalServerConfig { * Whether Gateway mode is available for app-level agent execution. */ enableGatewayMode?: boolean; - enableKlavis?: boolean; enableLobehubSkill?: boolean; enableMagicLink?: boolean; enableMarketTrustedClient?: boolean; diff --git a/packages/types/src/tool/plugin.ts b/packages/types/src/tool/plugin.ts index df87ae8603d..46f5c57e9c8 100644 --- a/packages/types/src/tool/plugin.ts +++ b/packages/types/src/tool/plugin.ts @@ -13,19 +13,18 @@ export interface CustomPluginMetadata { export interface CustomPluginParams { apiMode?: 'openapi' | 'simple'; avatar?: string; - description?: string; - enableSettings?: boolean; /** - * Klavis integration parameters + * Composio integration parameters */ - klavis?: { - instanceId: string; - isAuthenticated: boolean; - oauthUrl?: string; - serverName: string; - serverUrl: string; + composio?: { + appSlug: string; + authConfigId: string; + connectedAccountId: string; + redirectUrl?: string; + status: string; }; - + description?: string; + enableSettings?: boolean; manifestMode?: 'local' | 'url'; manifestUrl?: string; /** diff --git a/plugins/vite/nodeModuleStub.ts b/plugins/vite/nodeModuleStub.ts index f20cd54f522..49a74a12c57 100644 --- a/plugins/vite/nodeModuleStub.ts +++ b/plugins/vite/nodeModuleStub.ts @@ -5,7 +5,7 @@ import type { Plugin } from 'vite'; * * - `node:stream`: dynamically imported in azureai provider behind `typeof window === 'undefined'` * guard — dead code in browser but Rollup still resolves it. - * - `node-fetch`: dynamically imported by klavis SDK's getFetchFn behind a runtime + * - `node-fetch`: dynamically imported by composio SDK's getFetchFn behind a runtime * Node.js version check — dead code in browser since native fetch is available. */ export function viteNodeModuleStub(): Plugin { diff --git a/src/app/(backend)/api/composio/oauth/callback/route.ts b/src/app/(backend)/api/composio/oauth/callback/route.ts new file mode 100644 index 00000000000..2c44f598c8c --- /dev/null +++ b/src/app/(backend)/api/composio/oauth/callback/route.ts @@ -0,0 +1,36 @@ +import { type NextRequest, NextResponse } from 'next/server'; + +/** + * Composio OAuth callback. + * + * Composio uses managed auth — the provider token exchange happens on Composio's + * side, so this route does not exchange any code itself. It only lands the user + * back from the provider and closes the popup. The opener window detects the + * close and polls `composio.getConnection` to pick up the now-active connection + * and sync its tools. + */ +export const GET = async (req: NextRequest) => { + const searchParams = req.nextUrl.searchParams; + const status = searchParams.get('status') ?? undefined; + const oauthError = searchParams.get('error') ?? undefined; + + // Composio appends `status=success` / `status=failed` to the callback URL. + const success = !oauthError && status !== 'failed'; + + const html = ` + + Composio authorization + +

${success ? 'Authorization complete. You can close this window.' : 'Authorization failed.'}

+ + +`; + + return new NextResponse(html, { + headers: { 'content-type': 'text/html; charset=utf-8' }, + }); +}; diff --git a/src/components/ChangelogModal/ChangelogContent.tsx b/src/components/ChangelogModal/ChangelogContent.tsx index 5949a86bcf1..b9cf1c34b03 100644 --- a/src/components/ChangelogModal/ChangelogContent.tsx +++ b/src/components/ChangelogModal/ChangelogContent.tsx @@ -8,6 +8,7 @@ import urlJoin from 'url-join'; import { CustomMDX } from '@/components/mdx'; import { OFFICIAL_SITE } from '@/const/url'; +import { changelogKeys } from '@/libs/swr/keys'; import { lambdaClient } from '@/libs/trpc/client'; import { type Locales } from '@/locales/resources'; import { type ChangelogIndexItem } from '@/types/changelog'; @@ -24,7 +25,7 @@ interface PostItemProps extends ChangelogIndexItem { } const PostItem = ({ id, versionRange, locale, showDivider = true }: PostItemProps) => { - const { data } = useSWR([`changelog-post-${id}`, locale], async () => { + const { data } = useSWR(changelogKeys.post(id, locale), async () => { return await lambdaClient.changelog.getPostById.query({ id, locale }); }); diff --git a/src/components/ChangelogModal/ChangelogModalContent.tsx b/src/components/ChangelogModal/ChangelogModalContent.tsx index 6800c595c84..05ce761f21c 100644 --- a/src/components/ChangelogModal/ChangelogModalContent.tsx +++ b/src/components/ChangelogModal/ChangelogModalContent.tsx @@ -5,6 +5,7 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import useSWR from 'swr'; +import { changelogKeys } from '@/libs/swr/keys'; import { lambdaClient } from '@/libs/trpc/client'; import ChangelogContent from './ChangelogContent'; @@ -13,7 +14,7 @@ const SCROLL_HEIGHT = 'min(80vh, 760px)'; const ChangelogModalContent = memo(() => { const { t } = useTranslation('common'); - const { data, isLoading } = useSWR('changelog-modal-index', () => + const { data, isLoading } = useSWR(changelogKeys.modalIndex(), () => lambdaClient.changelog.getIndex.query(), ); diff --git a/src/features/AgentHome/AgentInfo.tsx b/src/features/AgentHome/AgentInfo.tsx index 8feb27fd220..76878b2746c 100644 --- a/src/features/AgentHome/AgentInfo.tsx +++ b/src/features/AgentHome/AgentInfo.tsx @@ -6,17 +6,26 @@ import { memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { DEFAULT_AVATAR, DEFAULT_INBOX_AVATAR } from '@/const/meta'; +import { contextSelectors, useConversationStore } from '@/features/Conversation/store'; import { useAgentStore } from '@/store/agent'; -import { agentSelectors, builtinAgentSelectors } from '@/store/agent/selectors'; +import { agentByIdSelectors, agentSelectors, builtinAgentSelectors } from '@/store/agent/selectors'; import { useUserStore } from '@/store/user'; import { userGeneralSettingsSelectors } from '@/store/user/slices/settings/selectors'; const AgentInfo = memo(() => { const { t } = useTranslation(['chat', 'welcome']); - const isLoading = useAgentStore(agentSelectors.isAgentConfigLoading); - const isInbox = useAgentStore(builtinAgentSelectors.isInboxAgent); - const meta = useAgentStore(agentSelectors.currentAgentMeta, isEqual); - const openingMessage = useAgentStore(agentSelectors.openingMessage); + // Scope the welcome to the conversation's agent, not the global + // `activeAgentId`. In the multi-tab desktop app `activeAgentId` is shared and + // can momentarily point at another tab's agent (or the inbox), which used to + // flash this card back to the inbox "Lobe AI" identity. + const agentId = useConversationStore(contextSelectors.agentId) || ''; + const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId); + const isInbox = !!inboxAgentId && agentId === inboxAgentId; + const isLoading = useAgentStore(agentByIdSelectors.isAgentConfigLoadingById(agentId)); + const meta = useAgentStore(agentSelectors.getAgentMetaById(agentId), isEqual); + const openingMessage = useAgentStore( + (s) => agentSelectors.getAgentConfigById(agentId)(s)?.openingMessage || '', + ); const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize); const displayTitle = isInbox diff --git a/src/features/AgentHome/RecentTopics.tsx b/src/features/AgentHome/RecentTopics.tsx index bc401a692da..b4643e513f6 100644 --- a/src/features/AgentHome/RecentTopics.tsx +++ b/src/features/AgentHome/RecentTopics.tsx @@ -10,6 +10,7 @@ import useSWR from 'swr'; import { SESSION_CHAT_TOPIC_URL } from '@/const/url'; import WorkspaceLink from '@/features/Workspace/WorkspaceLink'; +import { agentHomeKeys } from '@/libs/swr/keys'; import { topicService } from '@/services/topic'; import SectionHeader from './SectionHeader'; @@ -18,7 +19,7 @@ const AgentRecentTopics = memo(() => { const { t } = useTranslation('chat'); const { aid } = useParams<{ aid: string }>(); - const { data: result, isLoading } = useSWR(aid ? ['agentHome.topics', aid] : null, () => + const { data: result, isLoading } = useSWR(aid ? agentHomeKeys.topics(aid) : null, () => topicService.getTopics({ agentId: aid!, current: 0, pageSize: 10 }), ); diff --git a/src/features/AgentProfileCard/AgentProfilePopup.tsx b/src/features/AgentProfileCard/AgentProfilePopup.tsx index f54a4144ffb..baec6e4b34c 100644 --- a/src/features/AgentProfileCard/AgentProfilePopup.tsx +++ b/src/features/AgentProfileCard/AgentProfilePopup.tsx @@ -12,6 +12,7 @@ import useSWR from 'swr'; import ModelSelect from '@/features/ModelSelect'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; +import { agentProfileKeys } from '@/libs/swr/keys'; import { agentService } from '@/services/agent'; import { useAgentGroupStore } from '@/store/agentGroup'; @@ -78,7 +79,7 @@ const AgentProfilePopup = memo( const updateMemberAgentConfig = useAgentGroupStore((s) => s.updateMemberAgentConfig); const { data: fetched, isLoading } = useSWR( - open ? ['agentProfile', agentId] : null, + open ? agentProfileKeys.detail(agentId) : null, () => agentService.getAgentConfigById(agentId) as Promise, { revalidateOnFocus: false }, ); diff --git a/src/features/Auth/OAuthConsent/useInteractionDetails.ts b/src/features/Auth/OAuthConsent/useInteractionDetails.ts index cc68c227fa2..89c7762e170 100644 --- a/src/features/Auth/OAuthConsent/useInteractionDetails.ts +++ b/src/features/Auth/OAuthConsent/useInteractionDetails.ts @@ -1,5 +1,6 @@ import useSWR from 'swr'; +import { authKeys } from '@/libs/swr/keys'; import type { OidcInteractionDetailsResponse, OidcInteractionErrorResponse } from '@/types/oidc'; export class InteractionDetailsError extends Error { @@ -31,7 +32,7 @@ export const fetchInteractionDetails = async ( export const useInteractionDetails = (uid?: string) => useSWR( - uid ? ['oidc-interaction', uid] : null, + uid ? authKeys.oidcInteraction(uid) : null, ([, id]: [string, string]) => fetchInteractionDetails(id), { revalidateOnFocus: false, diff --git a/src/features/ChatInput/ActionBar/SaveTopic/index.tsx b/src/features/ChatInput/ActionBar/SaveTopic/index.tsx index e578185737a..fabe633a678 100644 --- a/src/features/ChatInput/ActionBar/SaveTopic/index.tsx +++ b/src/features/ChatInput/ActionBar/SaveTopic/index.tsx @@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next'; import { useIsMobile } from '@/hooks/useIsMobile'; import { usePermission } from '@/hooks/usePermission'; import { useActionSWR } from '@/libs/swr'; +import { topicActionKeys } from '@/libs/swr/keys'; import { useChatStore } from '@/store/chat'; import { useUserStore } from '@/store/user'; import { settingsSelectors } from '@/store/user/selectors'; @@ -23,7 +24,10 @@ const SaveTopic = memo(() => { const mobile = useIsMobile(); - const { mutate, isValidating } = useActionSWR('openNewTopicOrSaveTopic', openNewTopicOrSaveTopic); + const { mutate, isValidating } = useActionSWR( + topicActionKeys.openNewOrSave(), + openNewTopicOrSaveTopic, + ); const [confirmOpened, setConfirmOpened] = useState(false); diff --git a/src/features/ChatInput/ActionBar/Tools/KlavisServerItem.tsx b/src/features/ChatInput/ActionBar/Tools/ComposioServerItem.tsx similarity index 75% rename from src/features/ChatInput/ActionBar/Tools/KlavisServerItem.tsx rename to src/features/ChatInput/ActionBar/Tools/ComposioServerItem.tsx index 09f76574ffe..96f34b06673 100644 --- a/src/features/ChatInput/ActionBar/Tools/KlavisServerItem.tsx +++ b/src/features/ChatInput/ActionBar/Tools/ComposioServerItem.tsx @@ -7,8 +7,8 @@ import { usePermission } from '@/hooks/usePermission'; import { useAgentStore } from '@/store/agent'; import { agentSelectors } from '@/store/agent/selectors'; import { useToolStore } from '@/store/tool'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { useUserStore } from '@/store/user'; import { userProfileSelectors } from '@/store/user/selectors'; @@ -16,7 +16,7 @@ import { userProfileSelectors } from '@/store/user/selectors'; const POLL_INTERVAL_MS = 1000; // Poll once per second const POLL_TIMEOUT_MS = 15_000; // 15-second timeout -interface KlavisServerItemProps { +interface ComposioServerItemProps { /** * Optional agent ID to use instead of currentAgentConfig * Used in group profile to specify which member's plugins to toggle @@ -25,17 +25,17 @@ interface KlavisServerItemProps { /** * Identifier used for storage (e.g., 'google-calendar') */ - identifier: string; - label: string; - server?: KlavisServer; /** - * Server name used to call Klavis API (e.g., 'Google Calendar') + * Composio toolkit slug used to call the Composio API (e.g., 'GOOGLECALENDAR') */ - serverName: string; + appSlug: string; + identifier: string; + label: string; + server?: ComposioServer; } -const KlavisServerItem = memo( - ({ identifier, label, server, serverName, agentId }) => { +const ComposioServerItem = memo( + ({ appSlug, identifier, label, server, agentId }) => { const { t } = useTranslation('setting'); const [isConnecting, setIsConnecting] = useState(false); const [isToggling, setIsToggling] = useState(false); @@ -49,8 +49,9 @@ const KlavisServerItem = memo( const pollTimeoutRef = useRef | null>(null); const userId = useUserStore(userProfileSelectors.userId); - const createKlavisServer = useToolStore((s) => s.createKlavisServer); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); + const createComposioConnection = useToolStore((s) => s.createComposioConnection); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); + const reauthorizeComposioConnection = useToolStore((s) => s.reauthorizeComposioConnection); // Get effective agent ID (agentId prop or current active agent) const activeAgentId = useAgentStore((s) => s.activeAgentId); @@ -83,7 +84,7 @@ const KlavisServerItem = memo( // Stop all listeners when server status becomes CONNECTED useEffect(() => { - if (server?.status === KlavisServerStatus.CONNECTED && isWaitingAuth) { + if (server?.status === ComposioServerStatus.ACTIVE && isWaitingAuth) { cleanup(); } }, [server?.status, isWaitingAuth, cleanup, t]); @@ -99,9 +100,9 @@ const KlavisServerItem = memo( // Poll once per second pollIntervalRef.current = setInterval(async () => { try { - await refreshKlavisServerTools(serverName); + await refreshComposioConnectionStatus(serverName); } catch (error) { - console.info('[Klavis] Polling check (expected during auth):', error); + console.info('[Composio] Polling check (expected during auth):', error); } }, POLL_INTERVAL_MS); @@ -114,7 +115,7 @@ const KlavisServerItem = memo( setIsWaitingAuth(false); }, POLL_TIMEOUT_MS); }, - [refreshKlavisServerTools, t], + [refreshComposioConnectionStatus, t], ); /** @@ -139,7 +140,7 @@ const KlavisServerItem = memo( } } catch { // COOP blocked access, falling back to polling - console.info('[Klavis] COOP blocked window.closed access, falling back to polling'); + console.info('[Composio] COOP blocked window.closed access, falling back to polling'); if (windowCheckIntervalRef.current) { clearInterval(windowCheckIntervalRef.current); windowCheckIntervalRef.current = null; @@ -148,20 +149,20 @@ const KlavisServerItem = memo( } }, 500); }, - [refreshKlavisServerTools, startFallbackPolling], + [refreshComposioConnectionStatus, startFallbackPolling], ); /** * Open OAuth window */ const openOAuthWindow = useCallback( - (oauthUrl: string, serverName: string) => { + (redirectUrl: string, serverName: string) => { // Clean up previous state cleanup(); setIsWaitingAuth(true); // Open OAuth window - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; startWindowMonitor(oauthWindow, serverName); @@ -205,10 +206,10 @@ const KlavisServerItem = memo( setIsConnecting(true); try { - const newServer = await createKlavisServer({ + const newServer = await createComposioConnection({ + appSlug, identifier, - serverName, - userId, + label, }); if (newServer) { @@ -217,15 +218,15 @@ const KlavisServerItem = memo( await togglePlugin(newPluginId); // If already authenticated, refresh tool list directly, skip OAuth - if (newServer.isAuthenticated) { - await refreshKlavisServerTools(newServer.identifier); - } else if (newServer.oauthUrl) { + if (newServer.status === ComposioServerStatus.ACTIVE) { + await refreshComposioConnectionStatus(newServer.identifier); + } else if (newServer.redirectUrl) { // Need OAuth, open OAuth window and monitor close - openOAuthWindow(newServer.oauthUrl, newServer.identifier); + openOAuthWindow(newServer.redirectUrl, newServer.identifier); } } } catch (error) { - console.error('[Klavis] Failed to connect server:', error); + console.error('[Composio] Failed to connect server:', error); } finally { setIsConnecting(false); } @@ -238,6 +239,21 @@ const KlavisServerItem = memo( setIsToggling(false); }; + const handleReauthorize = async () => { + if (!canCreate || !canEdit || !server) return; + setIsConnecting(true); + try { + const newServer = await reauthorizeComposioConnection(server.identifier); + if (newServer?.redirectUrl) { + openOAuthWindow(newServer.redirectUrl, newServer.identifier); + } + } catch (error) { + console.error('[Composio] Failed to re-authorize server:', error); + } finally { + setIsConnecting(false); + } + }; + // Render right-side controls const renderRightControl = () => { // Connecting in progress @@ -263,7 +279,7 @@ const KlavisServerItem = memo( handleConnect(); }} > - {t('tools.klavis.connect', { defaultValue: 'Connect' })} + {t('tools.composio.connect', { defaultValue: 'Connect' })}
); @@ -271,7 +287,7 @@ const KlavisServerItem = memo( // Show different controls based on status switch (server.status) { - case KlavisServerStatus.CONNECTED: { + case ComposioServerStatus.ACTIVE: { // Toggling state if (isToggling) { return ; @@ -288,7 +304,8 @@ const KlavisServerItem = memo( /> ); } - case KlavisServerStatus.PENDING_AUTH: { + case ComposioServerStatus.PENDING_AUTH: + case ComposioServerStatus.ERROR: { // Waiting for authentication if (isWaitingAuth) { return ( @@ -297,33 +314,26 @@ const KlavisServerItem = memo( ); } + // Not yet authorized — show an explicit authorize affordance (matching + // other pending tools) so the row never looks connected. Clicking + // re-mints a fresh link (the prior one may have expired) and opens it. return ( { e.stopPropagation(); - if (!canEdit) return; - // Click to reopen OAuth window - if (server.oauthUrl) { - openOAuthWindow(server.oauthUrl, server.identifier); - } + if (!canCreate || !canEdit) return; + handleReauthorize(); }} > - {t('tools.klavis.pendingAuth', { defaultValue: 'Authorize' })} + {t('tools.composio.reauthorize', { defaultValue: 'Re-authorize' })} ); } - case KlavisServerStatus.ERROR: { - return ( - - {t('tools.klavis.error', { defaultValue: 'Error' })} - - ); - } default: { return null; } @@ -339,7 +349,7 @@ const KlavisServerItem = memo( onClick={(e) => { e.stopPropagation(); // If connected, clicking the row toggles state - if (canEdit && server?.status === KlavisServerStatus.CONNECTED) { + if (canEdit && server?.status === ComposioServerStatus.ACTIVE) { handleToggle(); } }} @@ -353,4 +363,4 @@ const KlavisServerItem = memo( }, ); -export default KlavisServerItem; +export default ComposioServerItem; diff --git a/src/features/ChatInput/ActionBar/Tools/KlavisSkillIcon.tsx b/src/features/ChatInput/ActionBar/Tools/ComposioSkillIcon.tsx similarity index 64% rename from src/features/ChatInput/ActionBar/Tools/KlavisSkillIcon.tsx rename to src/features/ChatInput/ActionBar/Tools/ComposioSkillIcon.tsx index 9b98a330483..c53c597183a 100644 --- a/src/features/ChatInput/ActionBar/Tools/KlavisSkillIcon.tsx +++ b/src/features/ChatInput/ActionBar/Tools/ComposioSkillIcon.tsx @@ -1,4 +1,4 @@ -import { type KlavisServerType } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; import { Icon } from '@lobehub/ui'; import { cssVar } from 'antd-style'; import { memo } from 'react'; @@ -6,9 +6,9 @@ import { memo } from 'react'; export const SKILL_ICON_SIZE = 20; /** - * Klavis server icon component + * Composio server icon component */ -const KlavisSkillIcon = memo & { size: number }>( +const ComposioSkillIcon = memo & { size: number }>( ({ icon, label, size = SKILL_ICON_SIZE }) => { if (typeof icon === 'string') { return ( @@ -24,6 +24,6 @@ const KlavisSkillIcon = memo & { size: }, ); -KlavisSkillIcon.displayName = 'KlavisSkillIcon'; +ComposioSkillIcon.displayName = 'ComposioSkillIcon'; -export default KlavisSkillIcon; +export default ComposioSkillIcon; diff --git a/src/features/ChatInput/ActionBar/Tools/useControls.tsx b/src/features/ChatInput/ActionBar/Tools/useControls.tsx index f50ebb78ca5..7b12226b31a 100644 --- a/src/features/ChatInput/ActionBar/Tools/useControls.tsx +++ b/src/features/ChatInput/ActionBar/Tools/useControls.tsx @@ -1,5 +1,5 @@ import { - KLAVIS_SERVER_TYPES, + COMPOSIO_APP_TYPES, LOBEHUB_SKILL_PROVIDERS, RECOMMENDED_SKILLS, RecommendedSkillType, @@ -42,18 +42,18 @@ import { useToolStore } from '@/store/tool'; import { agentSkillsSelectors, builtinToolSelectors, - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { connectorSelectors } from '@/store/tool/slices/connector'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import { useAgentId } from '../../hooks/useAgentId'; import { useUpdateAgentConfig } from '../../hooks/useUpdateAgentConfig'; -import KlavisServerItem from './KlavisServerItem'; -import KlavisSkillIcon from './KlavisSkillIcon'; +import ComposioServerItem from './ComposioServerItem'; +import ComposioSkillIcon from './ComposioSkillIcon'; import LobehubSkillIcon from './LobehubSkillIcon'; import LobehubSkillServerItem from './LobehubSkillServerItem'; import MarketAgentSkillPopoverContent from './MarketAgentSkillPopoverContent'; @@ -411,14 +411,14 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = const list = useToolStore(pluginSelectors.installedPluginMetaList, isEqual); const [ uninstallPlugin, - removeKlavisServer, + removeComposioConnection, deleteAgentSkill, installCustomPlugin, updateNewCustomPlugin, uninstallBuiltinTool, ] = useToolStore((s) => [ s.uninstallCustomPlugin, - s.removeKlavisServer, + s.removeComposioConnection, s.deleteAgentSkill, s.installCustomPlugin, s.updateNewCustomPlugin, @@ -697,9 +697,9 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = [renderPolicyMenu, renderToolLabel], ); - // Klavis-related state - const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); - const isKlavisEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableKlavis); + // Composio-related state + const allComposioServers = useToolStore(composioStoreSelectors.getServers, isEqual); + const isComposioEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableComposio); // LobeHub Skill related state const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual); @@ -719,12 +719,12 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = }, [isConnectorsInit, fetchConnectors]); const [ - useFetchUserKlavisServers, + useFetchUserComposioConnections, useFetchLobehubSkillConnections, useFetchUninstalledBuiltinTools, useFetchAgentSkills, ] = useToolStore((s) => [ - s.useFetchUserKlavisServers, + s.useFetchUserComposioConnections, s.useFetchLobehubSkillConnections, s.useFetchUninstalledBuiltinTools, s.useFetchAgentSkills, @@ -735,8 +735,8 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = useFetchAgentSkills(true); useCheckPluginsIsInstalled(plugins); - // Load user's Klavis integrations via SWR (from database) - useFetchUserKlavisServers(isKlavisEnabledInEnv); + // Load user's Composio integrations via SWR (from database) + useFetchUserComposioConnections(isComposioEnabledInEnv); // Load user's LobeHub Skill connections via SWR useFetchLobehubSkillConnections(isLobehubSkillEnabled); @@ -744,15 +744,15 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = // Get connected server by identifier const getServerByName = useCallback( (identifier: string) => { - return allKlavisServers.find((server) => server.identifier === identifier); + return allComposioServers.find((server) => server.identifier === identifier); }, - [allKlavisServers], + [allComposioServers], ); - // Get all Klavis server type identifier sets (used for filtering builtinList) - // Using KLAVIS_SERVER_TYPES instead of connected servers here, because we want to filter out all possible Klavis types - const allKlavisTypeIdentifiers = useMemo( - () => new Set(KLAVIS_SERVER_TYPES.map((type) => type.identifier)), + // Get all Composio server type identifier sets (used for filtering builtinList) + // Using COMPOSIO_APP_TYPES instead of connected servers here, because we want to filter out all possible Composio types + const allComposioTypeIdentifiers = useMemo( + () => new Set(COMPOSIO_APP_TYPES.map((type) => type.identifier)), [], ); // Get all skill identifier sets (used for filtering builtinList) @@ -764,20 +764,20 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = return ids; }, [installedBuiltinSkills, marketAgentSkills, userAgentSkills]); - // Filter out Klavis tools and skills from builtinList (they will be displayed separately) + // Filter out Composio tools and skills from builtinList (they will be displayed separately) const filteredBuiltinList = useMemo(() => { let list = builtinList; - if (isKlavisEnabledInEnv) { - list = list.filter((item) => !allKlavisTypeIdentifiers.has(item.identifier)); + if (isComposioEnabledInEnv) { + list = list.filter((item) => !allComposioTypeIdentifiers.has(item.identifier)); } return list.filter((item) => !allSkillIdentifiers.has(item.identifier)); - }, [builtinList, allKlavisTypeIdentifiers, isKlavisEnabledInEnv, allSkillIdentifiers]); + }, [builtinList, allComposioTypeIdentifiers, isComposioEnabledInEnv, allSkillIdentifiers]); - // Get recommended Klavis skill IDs - const recommendedKlavisIds = useMemo( + // Get recommended Composio skill IDs + const recommendedComposioIds = useMemo( () => new Set( - RECOMMENDED_SKILLS.filter((s) => s.type === RecommendedSkillType.Klavis).map((s) => s.id), + RECOMMENDED_SKILLS.filter((s) => s.type === RecommendedSkillType.Composio).map((s) => s.id), ), [], ); @@ -791,10 +791,10 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = [], ); - // Get installed Klavis server IDs - const installedKlavisIds = useMemo( - () => new Set(allKlavisServers.map((s) => s.identifier)), - [allKlavisServers], + // Get installed Composio server IDs + const installedComposioIds = useMemo( + () => new Set(allComposioServers.map((s) => s.identifier)), + [allComposioServers], ); // Get installed Lobehub skill IDs @@ -803,36 +803,36 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = [allLobehubSkillServers], ); - // Klavis server list items - only show installed or recommended - const klavisServerItems = useMemo( + // Composio server list items - only show installed or recommended + const composioServerItems = useMemo( () => - isKlavisEnabledInEnv - ? KLAVIS_SERVER_TYPES.filter( + isComposioEnabledInEnv + ? COMPOSIO_APP_TYPES.filter( (type) => - installedKlavisIds.has(type.identifier) || recommendedKlavisIds.has(type.identifier), + installedComposioIds.has(type.identifier) || recommendedComposioIds.has(type.identifier), ).map((type) => { const server = getServerByName(type.identifier); const icon = ( - + ); const popoverContent = ( } + icon={} identifier={type.identifier} sourceLabel={type.author} title={type.label} - description={t(`tools.klavis.servers.${type.identifier}.description` as any, { + description={t(`tools.composio.servers.${type.identifier}.description` as any, { defaultValue: type.description, })} /> ); - if (server?.status === KlavisServerStatus.CONNECTED) { + if (server?.status === ComposioServerStatus.ACTIVE) { return createManagedSkillItem({ badge: , deleteConfig: { displayName: type.label, - onDelete: () => removeKlavisServer(server.identifier), + onDelete: () => removeComposioConnection(server.identifier), }, extraTag: type.author === 'LobeHub' ? officialTag : undefined, icon, @@ -847,12 +847,12 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = icon, key: type.identifier, label: ( - ), popoverContent, @@ -861,14 +861,14 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = }) : [], [ - isKlavisEnabledInEnv, - installedKlavisIds, - recommendedKlavisIds, + isComposioEnabledInEnv, + installedComposioIds, + recommendedComposioIds, agentId, t, createManagedSkillItem, getServerByName, - removeKlavisServer, + removeComposioConnection, ], ); @@ -938,7 +938,7 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = ], ); - // Builtin tool list items (excluding Klavis and LobeHub Skill) + // Builtin tool list items (excluding Composio and LobeHub Skill) const builtinItems = useMemo( () => filteredBuiltinList.map((item) => { @@ -1197,10 +1197,10 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = [customConnectors, t, createManagedSkillItem], ); - // Skills list items (including LobeHub Skill and Klavis) + // Skills list items (including LobeHub Skill and Composio) // Connected items listed first, deduplicated by key (LobeHub takes priority) const skillItems = useMemo(() => { - // Deduplicate by key - LobeHub items take priority over Klavis + // Deduplicate by key - LobeHub items take priority over Composio const seenKeys = new Set(); const allItems: typeof lobehubSkillItems = []; @@ -1212,8 +1212,8 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = } } - // Add Klavis items only if not already present - for (const item of klavisServerItems) { + // Add Composio items only if not already present + for (const item of composioServerItems) { if (!seenKeys.has(item.key as string)) { seenKeys.add(item.key as string); allItems.push(item); @@ -1222,15 +1222,15 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = return allItems.sort((a, b) => { const isConnectedA = - installedLobehubIds.has(a.key as string) || installedKlavisIds.has(a.key as string); + installedLobehubIds.has(a.key as string) || installedComposioIds.has(a.key as string); const isConnectedB = - installedLobehubIds.has(b.key as string) || installedKlavisIds.has(b.key as string); + installedLobehubIds.has(b.key as string) || installedComposioIds.has(b.key as string); if (isConnectedA && !isConnectedB) return -1; if (!isConnectedA && isConnectedB) return 1; return 0; }); - }, [lobehubSkillItems, klavisServerItems, installedLobehubIds, installedKlavisIds]); + }, [lobehubSkillItems, composioServerItems, installedLobehubIds, installedComposioIds]); // Distinguish community plugins and custom plugins const communityPlugins = list.filter((item) => item.type !== 'customPlugin'); @@ -1291,13 +1291,13 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = }); }; - // Build LobeHub group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Klavis) + // Build LobeHub group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Composio) const lobehubGroupChildren: ItemType[] = [ // 1. Builtin Agent Skills ...builtinAgentSkillItems, // 2. Builtin tools ...builtinItems, - // 3. LobeHub Skill and Klavis (as builtin skills) + // 3. LobeHub Skill and Composio (as builtin skills) ...skillItems, ]; @@ -1547,8 +1547,8 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = ), })); - // Connected Klavis servers - const connectedKlavisItems = klavisServerItems.filter((item) => + // Connected Composio servers + const connectedComposioItems = composioServerItems.filter((item) => checked.includes(item.key as string), ); @@ -1557,8 +1557,8 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = checked.includes(item.key as string), ); - // Merge enabled LobeHub Skill and Klavis (as builtin skills) - const enabledSkillItems = [...connectedLobehubSkillItems, ...connectedKlavisItems]; + // Merge enabled LobeHub Skill and Composio (as builtin skills) + const enabledSkillItems = [...connectedLobehubSkillItems, ...connectedComposioItems]; // Enabled Builtin Agent Skills const enabledBuiltinAgentSkillItems = installedBuiltinSkills @@ -1608,7 +1608,7 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = ), })); - // Build builtin tools group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Klavis) + // Build builtin tools group children (including Builtin Agent Skills, builtin tools, and LobeHub Skill/Composio) const allBuiltinItems: ItemType[] = [ // 1. Builtin Agent Skills ...enabledBuiltinAgentSkillItems, @@ -1618,7 +1618,7 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = ...(enabledBuiltinItems.length > 0 && enabledSkillItems.length > 0 ? [{ key: 'installed-divider-builtin-skill', type: 'divider' as const }] : []), - // 4. LobeHub Skill and Klavis + // 4. LobeHub Skill and Composio ...enabledSkillItems, ]; @@ -1814,7 +1814,7 @@ export const useControls = ({ closeDropdown }: { closeDropdown?: () => void } = userAgentSkills, communityPlugins, customPlugins, - klavisServerItems, + composioServerItems, lobehubSkillItems, checked, togglePlugin, diff --git a/src/features/ChatInput/ControlBar/BranchSwitcher.tsx b/src/features/ChatInput/ControlBar/BranchSwitcher.tsx index fed8765a7f4..eac6e1e6fc2 100644 --- a/src/features/ChatInput/ControlBar/BranchSwitcher.tsx +++ b/src/features/ChatInput/ControlBar/BranchSwitcher.tsx @@ -32,6 +32,7 @@ import { useTranslation } from 'react-i18next'; import useSWR from 'swr'; import { message } from '@/components/AntdStaticMethods'; +import { deviceKeys } from '@/libs/swr/keys'; import { gitService } from '@/services/git'; import { useFetchGitWorkingTreeStatus } from '@/store/device'; @@ -243,7 +244,7 @@ const BranchSwitcher = memo( error: branchesError, mutate: mutateBranches, } = useSWR( - open ? ['git-branches', deviceId ?? 'local', path] : null, + open ? deviceKeys.gitBranches(deviceId ?? 'local', path) : null, () => gitService.listGitBranches({ deviceId, path }), { revalidateOnFocus: false, shouldRetryOnError: false }, ); diff --git a/src/features/ChatInput/ControlBar/useRepoType.ts b/src/features/ChatInput/ControlBar/useRepoType.ts index ae4e9c98025..449438412bc 100644 --- a/src/features/ChatInput/ControlBar/useRepoType.ts +++ b/src/features/ChatInput/ControlBar/useRepoType.ts @@ -2,6 +2,7 @@ import { isDesktop } from '@lobechat/const'; import { useEffect, useMemo } from 'react'; import useSWR from 'swr'; +import { deviceKeys } from '@/libs/swr/keys'; import { electronGitService } from '@/services/electron/git'; import { deviceSelectors, useDeviceStore } from '@/store/device'; import { useElectronStore } from '@/store/electron'; @@ -45,7 +46,7 @@ export const useRepoType = (path?: string, deviceId?: string): RepoType => { const shouldProbe = isDesktop && isLocalTarget && !!path && !cached; const { data: probed } = useSWR( - shouldProbe ? ['detect-repo-type', path] : null, + shouldProbe ? deviceKeys.repoType(path!) : null, () => electronGitService.detectRepoType(path!), { dedupingInterval: 60 * 1000, diff --git a/src/features/ChatInput/InputEditor/ActionTag/useInstalledSkillsAndTools.ts b/src/features/ChatInput/InputEditor/ActionTag/useInstalledSkillsAndTools.ts index 2b8616cddaf..1f6d91fbd3f 100644 --- a/src/features/ChatInput/InputEditor/ActionTag/useInstalledSkillsAndTools.ts +++ b/src/features/ChatInput/InputEditor/ActionTag/useInstalledSkillsAndTools.ts @@ -5,7 +5,7 @@ import { useToolStore } from '@/store/tool'; import { agentSkillsSelectors, builtinToolSelectors, - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; @@ -15,12 +15,12 @@ import type { ActionTagData } from './types'; /** * Collects all installed skills and tools, returning them as ActionTagData[]. * Skills: builtinSkills, lobehubSkillServers, marketAgentSkills, userAgentSkills - * Tools: installedPlugins (excluding skill-type entries), klavisServers + * Tools: installedPlugins (excluding skill-type entries), composioServers */ export const useInstalledSkillsAndTools = (): ActionTagData[] => { const builtinSkills = useToolStore(builtinToolSelectors.installedBuiltinSkills, isEqual); const installedPlugins = useToolStore(pluginSelectors.installedPluginMetaList, isEqual); - const klavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); + const composioServers = useToolStore(composioStoreSelectors.getServers, isEqual); const lobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual); const marketAgentSkills = useToolStore(agentSkillsSelectors.getMarketAgentSkills, isEqual); const userAgentSkills = useToolStore(agentSkillsSelectors.getUserAgentSkills, isEqual); @@ -60,12 +60,12 @@ export const useInstalledSkillsAndTools = (): ActionTagData[] => { toolMap.set(item.identifier, { icon: item.avatar, label: item.title || item.identifier }); } } - for (const item of klavisServers) { + for (const item of composioServers) { if (skillMap.has(item.identifier)) continue; if (!toolMap.has(item.identifier)) { toolMap.set(item.identifier, { icon: item.icon, - label: item.serverName || item.identifier, + label: item.label || item.identifier, }); } } @@ -82,7 +82,7 @@ export const useInstalledSkillsAndTools = (): ActionTagData[] => { }, [ builtinSkills, installedPlugins, - klavisServers, + composioServers, lobehubSkillServers, marketAgentSkills, userAgentSkills, diff --git a/src/features/Conversation/ChatList/hooks/useAgentSignalReceipts.ts b/src/features/Conversation/ChatList/hooks/useAgentSignalReceipts.ts index 289f8b8b1fa..9a76a26c91d 100644 --- a/src/features/Conversation/ChatList/hooks/useAgentSignalReceipts.ts +++ b/src/features/Conversation/ChatList/hooks/useAgentSignalReceipts.ts @@ -2,6 +2,7 @@ import type { UIChatMessage } from '@lobechat/types'; import { useMemo, useRef } from 'react'; import useSWR from 'swr'; +import { agentSignalKeys } from '@/libs/swr/keys'; import { agentSignalService } from '@/services/agentSignal'; /** Poll cadence for the active conversation's Agent Signal receipt surface. */ @@ -49,7 +50,7 @@ export const useAgentSignalReceipts = (input: { } const { data, isLoading } = useSWR( - shouldFetch ? ['agentSignalReceipts', input.agentId, input.topicId] : null, + shouldFetch ? agentSignalKeys.receipts(input.agentId!, input.topicId!) : null, async () => { const result = await agentSignalService.listReceipts({ agentId: input.agentId!, diff --git a/src/features/Conversation/Markdown/plugins/Mention/Render.tsx b/src/features/Conversation/Markdown/plugins/Mention/Render.tsx index 2860f98bf0d..d11f99e0a17 100644 --- a/src/features/Conversation/Markdown/plugins/Mention/Render.tsx +++ b/src/features/Conversation/Markdown/plugins/Mention/Render.tsx @@ -44,7 +44,7 @@ interface MentionProps { name: string; } const Render = memo>(({ children, node }) => { - const { id: mentionId } = node?.properties || {}; + const { id: mentionId, name } = node?.properties || {}; const { t } = useTranslation('chat'); const currentGroupMembers = useSessionStore(sessionSelectors.currentGroupAgents, isEqual); @@ -67,7 +67,7 @@ const Render = memo>(({ children, node }) => return ( {'@'} - {children || 'unknown'} + {name || children || 'unknown'} ); } @@ -95,7 +95,7 @@ const Render = memo>(({ children, node }) => > {'@'} - {member.title || children} + {member.title || name || children} ); diff --git a/src/features/Conversation/Messages/AssistantGroup/components/Group.test.tsx b/src/features/Conversation/Messages/AssistantGroup/components/Group.test.tsx index 8ae222bd4cb..ed5b96afa63 100644 --- a/src/features/Conversation/Messages/AssistantGroup/components/Group.test.tsx +++ b/src/features/Conversation/Messages/AssistantGroup/components/Group.test.tsx @@ -209,17 +209,17 @@ describe('Group', () => { ]); }); - it('keeps a mixed block full preamble visible above a folded multi-tool workflow', () => { - // The whole preamble (every sentence) stays in a visible answer segment; the - // workflow fold holds only the tools. Otherwise the prose past the first - // sentence would be hidden inside the collapsed-by-default workflow body. + it('keeps answer-like mixed prose visible above a folded multi-tool workflow', () => { + const answerLikePreamble = + 'I found the likely rendering issue and need to verify the grouped workflow behavior.\n\n- The assistant prose should remain above the fold when it explains the result.\n- The tools still belong in the collapsed workflow.\n- Short progress lines should not split the workflow.'; + const { container } = render( { expect(sequence).toEqual(['answer-segment', 'workflow-segment']); expect(parseAnswerSegment()).toEqual({ - content: '我先帮你查一下。接下来我会继续整理结果。', - contentOverride: '我先帮你查一下。接下来我会继续整理结果。', + content: answerLikePreamble, + contentOverride: answerLikePreamble, disableMarkdownStreaming: true, domId: 'block-1__answer', hasError: false, @@ -268,6 +268,50 @@ describe('Group', () => { ]); }); + it('folds consecutive short mixed single-tool blocks into one workflow segment', () => { + const { container } = render( + , + ); + + const sequence = Array.from(container.querySelectorAll('[data-testid]')).map((node) => + node.getAttribute('data-testid'), + ); + + expect(sequence).toEqual(['workflow-segment']); + expect(screen.queryByTestId('answer-segment')).not.toBeInTheDocument(); + expect(parseWorkflowSegment()).toEqual([ + { + content: 'Let me inspect the package scripts.', + disableMarkdownStreaming: true, + domId: undefined, + hasError: false, + toolCount: 1, + }, + { + content: 'Now let me read the source file.', + disableMarkdownStreaming: false, + domId: undefined, + hasError: false, + toolCount: 1, + }, + ]); + }); + it('keeps assistant runtime errors outside the workflow collapse', () => { const { container } = render( { + if (!hasTools(block) || !hasSubstantiveContent(block)) return false; + + return scoreBlockContentAsAnswerLike(block) >= POST_TOOL_FINAL_ANSWER_SCORE_THRESHOLD; +}; + const appendWorkflowRangeBlock = ( segments: GroupRenderSegment[], block: AssistantContentBlock, @@ -167,18 +178,11 @@ const appendWorkflowRangeBlock = ( return; } - // A block that carries both tool calls and prose keeps its NATURAL order - // (content above the tool). Within one assistant message the model's text - // always precedes its tool_use — tool_use ends the turn, so any post-tool - // prose lands in a separate, tool-less block. A mixed block's content is - // therefore always a preamble, never a post-tool summary. - // - // In a single-tool turn the block renders inline as-is (content above its - // tool). In a multi-tool turn the tools collapse into a WorkflowCollapse that - // defaults to folded once complete, so we lift the full preamble into its own - // visible answer segment first and leave only the tool(s) in the fold — - // otherwise the explanation would be hidden inside the collapsed body. - if (collapsesIntoWorkflow && hasTools(block) && hasSubstantiveContent(block)) { + // Mixed blocks keep their natural order: assistant prose precedes tool_use. + // Short step/status prose belongs with the workflow so adjacent tools can + // still fold together; answer-like prose is lifted above the fold so it does + // not disappear inside a collapsed WorkflowCollapse. + if (collapsesIntoWorkflow && shouldPromoteMixedBlockContent(block)) { appendAnswerBlock( segments, createAnswerRenderBlock(block, { diff --git a/src/features/Electron/updater/UpdateNotification.tsx b/src/features/Electron/updater/UpdateNotification.tsx index 26e3dbe741b..d3fbeecc4ca 100644 --- a/src/features/Electron/updater/UpdateNotification.tsx +++ b/src/features/Electron/updater/UpdateNotification.tsx @@ -1,6 +1,6 @@ import { type UpdateInfo } from '@lobechat/electron-client-ipc'; import { useWatchBroadcast } from '@lobechat/electron-client-ipc'; -import { Button, Flexbox, Icon } from '@lobehub/ui'; +import { Button, Flexbox, Icon, Markdown } from '@lobehub/ui'; import { Modal } from 'antd'; import { createStaticStyles, cssVar } from 'antd-style'; import { CircleFadingArrowUp } from 'lucide-react'; @@ -134,12 +134,18 @@ export const UpdateNotification: React.FC = () => {
{updateInfo?.version}
- {updateInfo?.releaseNotes && ( -
- )} + {updateInfo?.releaseNotes && + (typeof updateInfo.releaseNotes === 'string' ? ( +
+ {updateInfo.releaseNotes} +
+ ) : ( +
+ {updateInfo.releaseNotes.map((note) => ( + {note.note ?? ''} + ))} +
+ ))}
); } @@ -132,7 +132,7 @@ const Header = memo(({ type }) => { type="primary" onClick={handleConnectWithTracking} > - {t('tools.klavis.connect', { defaultValue: 'Connect' })} + {t('tools.composio.connect', { defaultValue: 'Connect' })} ); diff --git a/src/features/SkillStore/SkillDetail/KlavisSkillDetailContent.tsx b/src/features/SkillStore/SkillDetail/KlavisSkillDetailContent.tsx deleted file mode 100644 index 44b4313c740..00000000000 --- a/src/features/SkillStore/SkillDetail/KlavisSkillDetailContent.tsx +++ /dev/null @@ -1,22 +0,0 @@ -'use client'; - -import { type Klavis } from 'klavis'; - -import { KlavisDetailProvider } from './KlavisDetailProvider'; -import SkillDetailInner from './SkillDetailInner'; - -export interface KlavisSkillDetailContentProps { - identifier: string; - serverName: Klavis.McpServerName; -} - -export const KlavisSkillDetailContent = ({ - identifier, - serverName, -}: KlavisSkillDetailContentProps) => { - return ( - - - - ); -}; diff --git a/src/features/SkillStore/SkillDetail/SkillDetailInner.tsx b/src/features/SkillStore/SkillDetail/SkillDetailInner.tsx index 5d481587f35..c4c16198e23 100644 --- a/src/features/SkillStore/SkillDetail/SkillDetailInner.tsx +++ b/src/features/SkillStore/SkillDetail/SkillDetailInner.tsx @@ -18,7 +18,7 @@ const TabSkeleton = () => ( ); interface SkillDetailInnerProps { - type: 'builtin' | 'klavis' | 'lobehub'; + type: 'builtin' | 'composio' | 'lobehub'; } const SkillDetailInner = memo(({ type }) => { diff --git a/src/features/SkillStore/SkillDetail/index.tsx b/src/features/SkillStore/SkillDetail/index.tsx index 0116af2480b..8982482acb6 100644 --- a/src/features/SkillStore/SkillDetail/index.tsx +++ b/src/features/SkillStore/SkillDetail/index.tsx @@ -2,11 +2,10 @@ import { createModal } from '@lobehub/ui/base-ui'; import { t } from 'i18next'; -import { type Klavis } from 'klavis'; import { BuiltinAgentSkillDetailContent } from './BuiltinAgentSkillDetailContent'; import { BuiltinSkillDetailContent } from './BuiltinSkillDetailContent'; -import { KlavisSkillDetailContent } from './KlavisSkillDetailContent'; +import { ComposioSkillDetailContent } from './ComposioSkillDetailContent'; import { LobehubSkillDetailContent } from './LobehubSkillDetailContent'; export interface CreateBuiltinAgentSkillDetailModalOptions { @@ -37,17 +36,17 @@ export const createBuiltinSkillDetailModal = ({ width: 800, }); -export interface CreateKlavisSkillDetailModalOptions { +export interface CreateComposioSkillDetailModalOptions { identifier: string; - serverName: Klavis.McpServerName; + serverName: string; } -export const createKlavisSkillDetailModal = ({ +export const createComposioSkillDetailModal = ({ identifier, serverName, -}: CreateKlavisSkillDetailModalOptions) => +}: CreateComposioSkillDetailModalOptions) => createModal({ - content: , + content: , footer: null, title: t('dev.title.skillDetails', { ns: 'plugin' }), width: 800, diff --git a/src/features/SkillStore/SkillList/LobeHub/Item.tsx b/src/features/SkillStore/SkillList/LobeHub/Item.tsx index 4a1aaa6ecd6..8b2bfe35b32 100644 --- a/src/features/SkillStore/SkillList/LobeHub/Item.tsx +++ b/src/features/SkillStore/SkillList/LobeHub/Item.tsx @@ -3,7 +3,6 @@ import { ActionIcon, Block, DropdownMenu, Flexbox, Icon, stopPropagation } from '@lobehub/ui'; import { confirmModal } from '@lobehub/ui/base-ui'; import { cssVar } from 'antd-style'; -import type { Klavis } from 'klavis'; import { Loader2, MoreVerticalIcon, Plus, Unplug } from 'lucide-react'; import React, { memo } from 'react'; import { useTranslation } from 'react-i18next'; @@ -20,8 +19,8 @@ interface ItemProps { isConnected: boolean; label: string; onOpenDetail?: () => void; - serverName?: Klavis.McpServerName; - type: 'klavis' | 'lobehub'; + serverName?: string; + type: 'composio' | 'lobehub'; } const Item = memo( @@ -38,7 +37,8 @@ const Item = memo( }); // Get localized description - const i18nPrefix = type === 'klavis' ? 'tools.klavis.servers' : 'tools.lobehubSkill.providers'; + const i18nPrefix = + type === 'composio' ? 'tools.composio.servers' : 'tools.lobehubSkill.providers'; // @ts-ignore const localizedDescription = t(`${i18nPrefix}.${identifier}.description`, { defaultValue: description, diff --git a/src/features/SkillStore/SkillList/LobeHub/index.tsx b/src/features/SkillStore/SkillList/LobeHub/index.tsx index dbcad45d57e..331d5886e46 100644 --- a/src/features/SkillStore/SkillList/LobeHub/index.tsx +++ b/src/features/SkillStore/SkillList/LobeHub/index.tsx @@ -1,6 +1,6 @@ 'use client'; -import { KLAVIS_SERVER_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES, LOBEHUB_SKILL_PROVIDERS } from '@lobechat/const'; import { type BuiltinSkill, type LobeToolMeta } from '@lobechat/types'; import isEqual from 'fast-deep-equal'; import { memo, useCallback, useMemo } from 'react'; @@ -9,14 +9,14 @@ import { useTranslation } from 'react-i18next'; import { createBuiltinAgentSkillDetailModal, createBuiltinSkillDetailModal, - createKlavisSkillDetailModal, + createComposioSkillDetailModal, createLobehubSkillDetailModal, } from '@/features/SkillStore/SkillDetail'; import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig'; import { useToolStore } from '@/store/tool'; import { type ToolStoreState } from '@/store/tool/initialState'; -import { klavisStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/selectors'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { composioStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/selectors'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import BuiltinItem from '../Builtin/Item'; @@ -29,7 +29,7 @@ interface LobeHubListProps { keywords: string; } -// Selector to get only actual builtin tools (not including Klavis) +// Selector to get only actual builtin tools (not including Composio) const getBuiltinToolsOnly = (s: ToolStoreState): LobeToolMeta[] => { return s.builtinTools .filter((item) => !item.hidden) @@ -44,20 +44,20 @@ const getBuiltinToolsOnly = (s: ToolStoreState): LobeToolMeta[] => { export const LobeHubList = memo(({ keywords }) => { const { t } = useTranslation('setting'); const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill); - const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis); + const isComposioEnabled = useServerConfigStore(serverConfigSelectors.enableComposio); const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual); - const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); - // Use custom selector to get only actual builtin tools (not Klavis) + const allComposioServers = useToolStore(composioStoreSelectors.getServers, isEqual); + // Use custom selector to get only actual builtin tools (not Composio) const builtinTools = useToolStore(getBuiltinToolsOnly, isEqual); const builtinSkills = useToolStore((s) => s.builtinSkills, isEqual); - const [useFetchLobehubSkillConnections, useFetchUserKlavisServers] = useToolStore((s) => [ + const [useFetchLobehubSkillConnections, useFetchUserComposioConnections] = useToolStore((s) => [ s.useFetchLobehubSkillConnections, - s.useFetchUserKlavisServers, + s.useFetchUserComposioConnections, ]); useFetchLobehubSkillConnections(isLobehubSkillEnabled); - useFetchUserKlavisServers(isKlavisEnabled); + useFetchUserComposioConnections(isComposioEnabled); const getLobehubSkillServerByProvider = useCallback( (providerId: string) => { @@ -66,17 +66,17 @@ export const LobeHubList = memo(({ keywords }) => { [allLobehubSkillServers], ); - const getKlavisServerByIdentifier = useCallback( + const getComposioServerByIdentifier = useCallback( (identifier: string) => { - return allKlavisServers.find((server) => server.identifier === identifier); + return allComposioServers.find((server) => server.identifier === identifier); }, - [allKlavisServers], + [allComposioServers], ); const filteredItems = useMemo(() => { const items: Array< | { provider: (typeof LOBEHUB_SKILL_PROVIDERS)[number]; type: 'lobehub' } - | { serverType: (typeof KLAVIS_SERVER_TYPES)[number]; type: 'klavis' } + | { serverType: (typeof COMPOSIO_APP_TYPES)[number]; type: 'composio' } | { skill: BuiltinSkill; type: 'builtinAgentSkill' } | { tool: LobeToolMeta; type: 'builtin' } > = []; @@ -98,10 +98,10 @@ export const LobeHubList = memo(({ keywords }) => { } } - // Add Klavis skills - if (isKlavisEnabled) { - for (const serverType of KLAVIS_SERVER_TYPES) { - items.push({ serverType, type: 'klavis' }); + // Add Composio skills + if (isComposioEnabled) { + for (const serverType of COMPOSIO_APP_TYPES) { + items.push({ serverType, type: 'composio' }); } } @@ -123,7 +123,7 @@ export const LobeHubList = memo(({ keywords }) => { const label = item.type === 'lobehub' ? item.provider.label : item.serverType.label; return label.toLowerCase().includes(lowerKeywords); }); - }, [keywords, isLobehubSkillEnabled, isKlavisEnabled, builtinTools, builtinSkills]); + }, [keywords, isLobehubSkillEnabled, isComposioEnabled, builtinTools, builtinSkills]); const hasSearchKeywords = Boolean(keywords && keywords.trim()); @@ -189,8 +189,8 @@ export const LobeHubList = memo(({ keywords }) => { /> ); } - const server = getKlavisServerByIdentifier(item.serverType.identifier); - const isConnected = server?.status === KlavisServerStatus.CONNECTED; + const server = getComposioServerByIdentifier(item.serverType.identifier); + const isConnected = server?.status === ComposioServerStatus.ACTIVE; return ( (({ keywords }) => { isConnected={isConnected} key={item.serverType.identifier} label={item.serverType.label} - serverName={item.serverType.serverName} - type="klavis" + serverName={item.serverType.appSlug} + type="composio" onOpenDetail={() => - createKlavisSkillDetailModal({ + createComposioSkillDetailModal({ identifier: item.serverType.identifier, - serverName: item.serverType.serverName, + serverName: item.serverType.appSlug, }) } /> diff --git a/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts b/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts index 2541b8506e9..cf6e633debc 100644 --- a/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts +++ b/src/features/SkillStore/SkillList/LobeHub/useSkillConnect.ts @@ -1,12 +1,11 @@ 'use client'; -import { getLobehubSkillProviderById } from '@lobechat/const'; -import { type Klavis } from 'klavis'; +import { COMPOSIO_APP_TYPES, getLobehubSkillProviderById } from '@lobechat/const'; import { useCallback, useEffect, useRef, useState } from 'react'; import { useToolStore } from '@/store/tool'; -import { klavisStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/selectors'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { composioStoreSelectors, lobehubSkillStoreSelectors } from '@/store/tool/selectors'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import { useUserStore } from '@/store/user'; import { userProfileSelectors } from '@/store/user/selectors'; @@ -16,8 +15,8 @@ const POLL_TIMEOUT_MS = 15_000; interface UseSkillConnectOptions { identifier: string; - serverName?: Klavis.McpServerName; - type: 'klavis' | 'lobehub'; + serverName?: string; + type: 'composio' | 'lobehub'; } export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnectOptions) => { @@ -35,12 +34,12 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec const getAuthorizeUrl = useToolStore((s) => s.getLobehubSkillAuthorizeUrl); const lobehubServer = useToolStore(lobehubSkillStoreSelectors.getServerByIdentifier(identifier)); - // Klavis hooks + // Composio hooks const userId = useUserStore(userProfileSelectors.userId); - const createKlavisServer = useToolStore((s) => s.createKlavisServer); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); - const removeKlavisServer = useToolStore((s) => s.removeKlavisServer); - const klavisServer = useToolStore(klavisStoreSelectors.getServerByIdentifier(identifier)); + const createComposioConnection = useToolStore((s) => s.createComposioConnection); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); + const removeComposioConnection = useToolStore((s) => s.removeComposioConnection); + const composioServer = useToolStore(composioStoreSelectors.getServerByIdentifier(identifier)); const cleanup = useCallback(() => { if (windowCheckIntervalRef.current) { @@ -69,12 +68,12 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec const connected = type === 'lobehub' ? lobehubServer?.status === LobehubSkillStatus.CONNECTED - : klavisServer?.status === KlavisServerStatus.CONNECTED; + : composioServer?.status === ComposioServerStatus.ACTIVE; if (connected && isWaitingAuth) { cleanup(); } - }, [type, lobehubServer?.status, klavisServer?.status, isWaitingAuth, cleanup]); + }, [type, lobehubServer?.status, composioServer?.status, isWaitingAuth, cleanup]); // Listen for OAuth success message from popup window (for LobeHub skills) useEffect(() => { @@ -105,7 +104,7 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec if (type === 'lobehub') { await checkLobehubStatus(serverIdOrName); } else { - await refreshKlavisServerTools(serverIdOrName); + await refreshComposioConnectionStatus(serverIdOrName); } } catch (error) { console.error('[SkillStore] Failed to check status:', error); @@ -120,7 +119,7 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec setIsWaitingAuth(false); }, POLL_TIMEOUT_MS); }, - [type, checkLobehubStatus, refreshKlavisServerTools], + [type, checkLobehubStatus, refreshComposioConnectionStatus], ); const startWindowMonitor = useCallback( @@ -137,7 +136,7 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec if (type === 'lobehub') { await checkLobehubStatus(serverIdOrName); } else { - await refreshKlavisServerTools(serverIdOrName); + await refreshComposioConnectionStatus(serverIdOrName); } setIsWaitingAuth(false); } @@ -150,15 +149,15 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec } }, 500); }, - [type, checkLobehubStatus, refreshKlavisServerTools, startFallbackPolling], + [type, checkLobehubStatus, refreshComposioConnectionStatus, startFallbackPolling], ); const openOAuthWindow = useCallback( - (oauthUrl: string, serverIdOrName: string) => { + (redirectUrl: string, serverIdOrName: string) => { cleanup(); setIsWaitingAuth(true); - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; startWindowMonitor(oauthWindow, serverIdOrName); @@ -191,24 +190,26 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec } }, [identifier, lobehubServer?.isConnected, getAuthorizeUrl, openOAuthWindow]); - // Handle connect for Klavis - const handleKlavisConnect = useCallback(async () => { - if (!userId || !serverName) return; - if (klavisServer) return; + // Handle connect for Composio + const handleComposioConnect = useCallback(async () => { + if (!userId) return; + if (composioServer) return; + + const appType = COMPOSIO_APP_TYPES.find((t) => t.identifier === identifier); setIsConnecting(true); try { - const newServer = await createKlavisServer({ + const newServer = await createComposioConnection({ + appSlug: appType?.appSlug ?? serverName ?? identifier, identifier, - serverName, - userId, + label: appType?.label ?? identifier, }); if (newServer) { - if (newServer.isAuthenticated) { - await refreshKlavisServerTools(newServer.identifier); - } else if (newServer.oauthUrl) { - openOAuthWindow(newServer.oauthUrl, newServer.identifier); + if (newServer.status === ComposioServerStatus.ACTIVE) { + await refreshComposioConnectionStatus(newServer.identifier); + } else if (newServer.redirectUrl) { + openOAuthWindow(newServer.redirectUrl, newServer.identifier); } } } catch (error) { @@ -219,27 +220,27 @@ export const useSkillConnect = ({ identifier, serverName, type }: UseSkillConnec }, [ userId, serverName, - klavisServer, + composioServer, identifier, - createKlavisServer, - refreshKlavisServerTools, + createComposioConnection, + refreshComposioConnectionStatus, openOAuthWindow, ]); - const handleConnect = type === 'lobehub' ? handleLobehubConnect : handleKlavisConnect; + const handleConnect = type === 'lobehub' ? handleLobehubConnect : handleComposioConnect; const handleDisconnect = useCallback(async () => { if (type === 'lobehub' && lobehubServer) { await revokeLobehubConnect(lobehubServer.identifier); - } else if (type === 'klavis' && klavisServer) { - await removeKlavisServer(klavisServer.identifier); + } else if (type === 'composio' && composioServer) { + await removeComposioConnection(composioServer.identifier); } - }, [type, lobehubServer, klavisServer, revokeLobehubConnect, removeKlavisServer]); + }, [type, lobehubServer, composioServer, revokeLobehubConnect, removeComposioConnection]); const isConnected = type === 'lobehub' ? lobehubServer?.status === LobehubSkillStatus.CONNECTED - : klavisServer?.status === KlavisServerStatus.CONNECTED; + : composioServer?.status === ComposioServerStatus.ACTIVE; return { handleConnect, diff --git a/src/features/SkillStore/SkillList/MarketSkills/index.tsx b/src/features/SkillStore/SkillList/MarketSkills/index.tsx index ef8a384377e..eb7f1ef63a0 100644 --- a/src/features/SkillStore/SkillList/MarketSkills/index.tsx +++ b/src/features/SkillStore/SkillList/MarketSkills/index.tsx @@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next'; import { VirtuosoGrid } from 'react-virtuoso'; import { useClientDataSWR } from '@/libs/swr'; +import { discoverKeys } from '@/libs/swr/keys'; import { discoverService } from '@/services/discover'; import { globalHelpers } from '@/store/global/helpers'; import { useToolStore } from '@/store/tool'; @@ -38,7 +39,7 @@ const MarketSkillList = memo(({ keywords }) => { const locale = globalHelpers.getCurrentLanguage(); const { data, isLoading, error } = useClientDataSWR( - ['skill-store-market-skills', locale, keywords || '', page].filter(Boolean).join('-'), + discoverKeys.skillStoreMarketSkills(locale, keywords || '', page), () => discoverService.getSkillList({ page, diff --git a/src/features/ToolTag/index.tsx b/src/features/ToolTag/index.tsx index cb48c1d4cbc..b982e4ffc29 100644 --- a/src/features/ToolTag/index.tsx +++ b/src/features/ToolTag/index.tsx @@ -1,7 +1,7 @@ 'use client'; -import { type KlavisServerType } from '@lobechat/const'; -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { Avatar, Icon, Tag } from '@lobehub/ui'; import { createStaticStyles, cssVar } from 'antd-style'; import isEqual from 'fast-deep-equal'; @@ -14,14 +14,14 @@ import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfi import { useToolStore } from '@/store/tool'; import { builtinToolSelectors, - klavisStoreSelectors, + composioStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; /** - * Klavis server icon component + * Composio server icon component */ -const KlavisIcon = memo>(({ icon, label }) => { +const ComposioIcon = memo>(({ icon, label }) => { if (typeof icon === 'string') { return {label}; } @@ -68,26 +68,26 @@ const ToolTag = memo(({ identifier, variant = 'default' }) => { const builtinList = useToolStore(builtinToolSelectors.metaList, isEqual); const installedPluginList = useToolStore(pluginSelectors.installedPluginMetaList, isEqual); - // Klavis related state - const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); - const isKlavisEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableKlavis); + // Composio related state + const allComposioServers = useToolStore(composioStoreSelectors.getServers, isEqual); + const isComposioEnabledInEnv = useServerConfigStore(serverConfigSelectors.enableComposio); // Check if plugin is installed const isInstalled = useToolStore(pluginSelectors.isPluginInstalled(identifier)); - // Try to find in local lists first (including Klavis) + // Try to find in local lists first (including Composio) const localMeta = useMemo(() => { - // Check if it's a Klavis server type - if (isKlavisEnabledInEnv) { - const klavisType = KLAVIS_SERVER_TYPES.find((type) => type.identifier === identifier); - if (klavisType) { - const connectedServer = allKlavisServers.find((s) => s.identifier === identifier); + // Check if it's a Composio server type + if (isComposioEnabledInEnv) { + const composioType = COMPOSIO_APP_TYPES.find((type) => type.identifier === identifier); + if (composioType) { + const connectedServer = allComposioServers.find((s) => s.identifier === identifier); return { - icon: klavisType.icon, + icon: composioType.icon, isInstalled: !!connectedServer, - label: klavisType.label, - title: klavisType.label, - type: 'klavis' as const, + label: composioType.label, + title: composioType.label, + type: 'composio' as const, }; } } @@ -113,7 +113,7 @@ const ToolTag = memo(({ identifier, variant = 'default' }) => { } return null; - }, [identifier, builtinList, installedPluginList, isKlavisEnabledInEnv, allKlavisServers]); + }, [identifier, builtinList, installedPluginList, isComposioEnabledInEnv, allComposioServers]); // Fetch from remote if not found locally const usePluginDetail = useDiscoverStore((s) => s.usePluginDetail); @@ -134,9 +134,9 @@ const ToolTag = memo(({ identifier, variant = 'default' }) => { // Render icon based on type const renderIcon = () => { - // Klavis type has icon property - if (meta.type === 'klavis' && 'icon' in meta && 'label' in meta) { - return ; + // Composio type has icon property + if (meta.type === 'composio' && 'icon' in meta && 'label' in meta) { + return ; } // Builtin type has avatar diff --git a/src/features/User/DataStatistics.tsx b/src/features/User/DataStatistics.tsx index 18333059f85..38e9a760c68 100644 --- a/src/features/User/DataStatistics.tsx +++ b/src/features/User/DataStatistics.tsx @@ -10,6 +10,7 @@ import { useTranslation } from 'react-i18next'; import NeuralNetworkLoading from '@/components/NeuralNetworkLoading'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import { sessionService } from '@/services/session'; import { topicService } from '@/services/topic'; @@ -46,16 +47,17 @@ const styles = createStaticStyles(({ css, cssVar }) => ({ const DataStatistics = memo>(({ style, ...rest }) => { const mobile = useServerConfigStore((s) => s.isMobile); // sessions - const { data: sessions, isLoading: sessionsLoading } = useClientDataSWR('count-sessions', () => - sessionService.countSessions(), + const { data: sessions, isLoading: sessionsLoading } = useClientDataSWR( + statsKeys.countSessions(), + () => sessionService.countSessions(), ); // topics - const { data: topics, isLoading: topicsLoading } = useClientDataSWR('count-topics', () => + const { data: topics, isLoading: topicsLoading } = useClientDataSWR(statsKeys.countTopics(), () => topicService.countTopics(), ); // messages const { data: { messages, messagesToday } = {}, isLoading: messagesLoading } = useClientDataSWR( - 'count-messages', + statsKeys.countMessages(), async () => ({ messages: await messageService.countMessages(), messagesToday: await messageService.countMessages({ diff --git a/src/features/Verify/hooks.ts b/src/features/Verify/hooks.ts index 2b7433c0139..24b3a137187 100644 --- a/src/features/Verify/hooks.ts +++ b/src/features/Verify/hooks.ts @@ -1,39 +1,34 @@ import { useClientDataSWR } from '@/libs/swr'; +import { verifyKeys } from '@/libs/swr/keys'; import { documentService } from '@/services/document'; import { verifyService } from '@/services/verify'; -export const VERIFY_STATE_KEY = 'verify-state'; -export const VERIFY_RESULTS_KEY = 'verify-results'; -export const VERIFY_TRACING_KEY = 'verify-tracing'; -export const VERIFY_INSTRUCTION_KEY = 'verify-instruction'; -export const VERIFY_RUBRIC_KEY = 'verify-rubric'; - /** Plan + rollup status for one Agent Run. Pass null operationId to skip. */ export const useVerifyState = (operationId: string | null) => - useClientDataSWR(operationId ? [VERIFY_STATE_KEY, operationId] : null, () => + useClientDataSWR(operationId ? verifyKeys.state(operationId) : null, () => verifyService.getVerifyState(operationId!), ); /** Per-item check results for one Agent Run. Pass null operationId to skip. */ export const useVerifyResults = (operationId: string | null) => - useClientDataSWR(operationId ? [VERIFY_RESULTS_KEY, operationId] : null, () => + useClientDataSWR(operationId ? verifyKeys.results(operationId) : null, () => verifyService.listResults(operationId!), ); /** Model / token / latency for an LLM verifier judgment. Pass null to skip. */ export const useVerifierTracing = (tracingId: string | null | undefined) => - useClientDataSWR(tracingId ? [VERIFY_TRACING_KEY, tracingId] : null, () => + useClientDataSWR(tracingId ? verifyKeys.tracing(tracingId) : null, () => verifyService.getVerifierTracing(tracingId!), ); /** The criterion's original judging rule, stored in its instruction document. */ export const useVerifyInstruction = (documentId: string | null | undefined) => - useClientDataSWR(documentId ? [VERIFY_INSTRUCTION_KEY, documentId] : null, () => + useClientDataSWR(documentId ? verifyKeys.instruction(documentId) : null, () => documentService.getDocumentById(documentId!), ); /** A rubric and its run-policy config (e.g. maxRepairRounds). Pass null to skip. */ export const useRubric = (rubricId: string | null | undefined) => - useClientDataSWR(rubricId ? [VERIFY_RUBRIC_KEY, rubricId] : null, () => + useClientDataSWR(rubricId ? verifyKeys.rubric(rubricId) : null, () => verifyService.getRubric(rubricId!), ); diff --git a/src/helpers/toolEngineering/index.test.ts b/src/helpers/toolEngineering/index.test.ts index a60c19d9d27..bc68d19c214 100644 --- a/src/helpers/toolEngineering/index.test.ts +++ b/src/helpers/toolEngineering/index.test.ts @@ -105,8 +105,8 @@ vi.mock('@/store/tool/selectors', () => ({ getInstalledPluginById: (id: string) => mockGetInstalledPluginById(id), installedPluginManifestList: () => mockInstalledPluginManifestList(), }, - klavisStoreSelectors: { - klavisAsLobeTools: () => [], + composioStoreSelectors: { + composioAsLobeTools: () => [], }, lobehubSkillStoreSelectors: { lobehubSkillAsLobeTools: () => [], diff --git a/src/helpers/toolEngineering/index.ts b/src/helpers/toolEngineering/index.ts index a5ebb747caf..815ee33919a 100644 --- a/src/helpers/toolEngineering/index.ts +++ b/src/helpers/toolEngineering/index.ts @@ -18,7 +18,7 @@ import { getAgentStoreState } from '@/store/agent'; import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors'; import { getToolStoreState } from '@/store/tool'; import { - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; @@ -46,7 +46,7 @@ export interface ToolsEngineConfig { * A manifest is usable by ToolsEngine only if it has a non-empty `api` array. * ToolsEngine.convertManifestsToTools calls `manifest.api.map(...)` unconditionally, * so any entry with `api` missing / non-array will crash the whole tools build. - * Sources that populate manifests (installed plugins, Klavis, LobeHub skills, MCP) + * Sources that populate manifests (installed plugins, Composio, LobeHub skills, MCP) * have no shared schema validation, so we guard defensively at the merge point. */ const isValidToolManifest = (m: ToolManifest | undefined): m is ToolManifest => @@ -123,9 +123,9 @@ export const createToolsEngine = (config: ToolsEngineConfig = {}): ToolsEngine = // Get all builtin tool manifests const builtinManifests = toolStoreState.builtinTools.map((tool) => tool.manifest as ToolManifest); - // Get Klavis tool manifests - const klavisTools = klavisStoreSelectors.klavisAsLobeTools(toolStoreState); - const klavisManifests = klavisTools.map((tool) => tool.manifest as ToolManifest).filter(Boolean); + // Get Composio tool manifests + const composioTools = composioStoreSelectors.composioAsLobeTools(toolStoreState); + const composioManifests = composioTools.map((tool) => tool.manifest as ToolManifest).filter(Boolean); // Get LobeHub Skill tool manifests const lobehubSkillTools = lobehubSkillStoreSelectors.lobehubSkillAsLobeTools(toolStoreState); @@ -138,7 +138,7 @@ export const createToolsEngine = (config: ToolsEngineConfig = {}): ToolsEngine = const allManifests = [ ...dropInvalidManifests(pluginManifests, 'installedPlugins'), ...dropInvalidManifests(builtinManifests, 'builtinTools'), - ...dropInvalidManifests(klavisManifests, 'klavis'), + ...dropInvalidManifests(composioManifests, 'composio'), ...dropInvalidManifests(lobehubSkillManifests, 'lobehubSkills'), ...dropInvalidManifests(connectorManifests, 'connectors'), ...dropInvalidManifests(additionalManifests, 'additionalManifests'), diff --git a/src/hooks/useGatewayReconnect.ts b/src/hooks/useGatewayReconnect.ts index e028189f3dd..d23fbeb27bc 100644 --- a/src/hooks/useGatewayReconnect.ts +++ b/src/hooks/useGatewayReconnect.ts @@ -1,5 +1,6 @@ import useSWR from 'swr'; +import { gatewayKeys } from '@/libs/swr/keys'; import { useChatStore } from '@/store/chat'; import { useServerConfigStore } from '@/store/serverConfig'; @@ -32,7 +33,7 @@ export const useGatewayReconnect = ( useSWR( runningOperation && topicId && agentGatewayUrl - ? ['reconnectGateway', runningOperation.operationId] + ? gatewayKeys.reconnect(runningOperation.operationId) : null, async () => { if (!runningOperation || !topicId) return; diff --git a/src/hooks/useHomeDailyBrief.ts b/src/hooks/useHomeDailyBrief.ts index d4252e694b3..b1a4839c676 100644 --- a/src/hooks/useHomeDailyBrief.ts +++ b/src/hooks/useHomeDailyBrief.ts @@ -1,12 +1,11 @@ import { useCallback, useEffect, useRef, useSyncExternalStore } from 'react'; import { useClientDataSWR } from '@/libs/swr'; +import { homeKeys } from '@/libs/swr/keys'; import { homeService } from '@/services/home'; import { useUserStore } from '@/store/user'; import { authSelectors, userProfileSelectors } from '@/store/user/selectors'; -const FETCH_HOME_DAILY_BRIEF_KEY = 'fetchHomeDailyBrief'; - interface HomeDailyBriefPair { hint: string; welcome: string; @@ -53,9 +52,8 @@ export const useHomeDailyBrief = (): UseHomeDailyBriefResult => { // Scope the SWR key by userId so an account switch within the same SPA // session (or signing in as a different user after sign-out) refetches // and never serves the previous user's cached pairs from this slot. - const { data } = useClientDataSWR( - isLogin && userId ? [FETCH_HOME_DAILY_BRIEF_KEY, userId] : null, - () => homeService.getDailyBrief(), + const { data } = useClientDataSWR(isLogin && userId ? homeKeys.dailyBrief(userId) : null, () => + homeService.getDailyBrief(), ); // Reset the module-level rotation when the user changes — otherwise the diff --git a/src/hooks/useHotkeys/chatScope.ts b/src/hooks/useHotkeys/chatScope.ts index 9655574028d..5d974e2f56a 100644 --- a/src/hooks/useHotkeys/chatScope.ts +++ b/src/hooks/useHotkeys/chatScope.ts @@ -4,6 +4,7 @@ import { useHotkeysContext } from 'react-hotkeys-hook'; import { useOpenChatSettings } from '@/hooks/useInterceptingRoutes'; import { useActionSWR } from '@/libs/swr'; +import { topicActionKeys } from '@/libs/swr/keys'; import { useChatStore } from '@/store/chat'; import { useGlobalStore } from '@/store/global'; @@ -11,7 +12,7 @@ import { useHotkeyById } from './useHotkeyById'; export const useSaveTopicHotkey = () => { const openNewTopicOrSaveTopic = useChatStore((s) => s.openNewTopicOrSaveTopic); - const { mutate } = useActionSWR('openNewTopicOrSaveTopic', openNewTopicOrSaveTopic); + const { mutate } = useActionSWR(topicActionKeys.openNewOrSave(), openNewTopicOrSaveTopic); return useHotkeyById(HotkeyEnum.SaveTopic, () => mutate(), { enableOnContentEditable: true }); }; diff --git a/src/hooks/usePrefetchAgent.ts b/src/hooks/usePrefetchAgent.ts index 9a19943a778..08222fc74fb 100644 --- a/src/hooks/usePrefetchAgent.ts +++ b/src/hooks/usePrefetchAgent.ts @@ -1,19 +1,26 @@ import { useCallback } from 'react'; -import { mutate } from '@/libs/swr'; +import { getActiveWorkspaceId } from '@/business/client/hooks/useActiveWorkspaceId'; +import { augmentKey, mutate } from '@/libs/swr'; +import { agentConfigKeys } from '@/libs/swr/keys'; import { agentService } from '@/services/agent'; -const FETCH_AGENT_CONFIG_KEY = 'FETCH_AGENT_CONFIG'; - /** * Returns a callback to prefetch agent config data into the SWR cache. * Call the returned function on mouseEnter to warm the cache before navigation. + * + * Warms the exact key `useFetchAgentConfig` reads — the workspace-augmented + * form of `agentConfigKeys.config(agentId)` — so the prefetch actually hits the + * consumer's cache entry. */ export const usePrefetchAgent = () => { return useCallback((agentId: string) => { if (!agentId) return; - const key = [FETCH_AGENT_CONFIG_KEY, agentId] as const; + const key = augmentKey( + agentConfigKeys.config(agentId), + getActiveWorkspaceId(), + ) as readonly unknown[]; // Populate the SWR cache without triggering re-renders on consuming hooks mutate(key, agentService.getAgentConfigById(agentId), { diff --git a/src/layout/AuthProvider/MarketAuth/useSocialConnect.ts b/src/layout/AuthProvider/MarketAuth/useSocialConnect.ts index ad3476e1fb2..3c6b30c38a6 100644 --- a/src/layout/AuthProvider/MarketAuth/useSocialConnect.ts +++ b/src/layout/AuthProvider/MarketAuth/useSocialConnect.ts @@ -228,13 +228,13 @@ export const useSocialConnect = ({ // Open OAuth popup window const openOAuthWindow = useCallback( - (oauthUrl: string) => { + (redirectUrl: string) => { cleanup(); authCompletedRef.current = false; setIsWaitingAuth(true); setError(null); - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; startWindowMonitor(oauthWindow); diff --git a/src/libs/composio/index.ts b/src/libs/composio/index.ts new file mode 100644 index 00000000000..eaebd5474ef --- /dev/null +++ b/src/libs/composio/index.ts @@ -0,0 +1,26 @@ +import { Composio } from '@composio/core'; + +import { getServerComposioApiKey } from '@/config/composio'; + +let composioClientInstance: { apiKey: string; client: Composio } | undefined; + +export const getComposioClient = (): Composio => { + const apiKey = getServerComposioApiKey(); + + if (!apiKey) { + throw new Error('Composio API key is not configured on server'); + } + + if (!composioClientInstance || composioClientInstance.apiKey !== apiKey) { + composioClientInstance = { + apiKey, + client: new Composio({ apiKey }), + }; + } + + return composioClientInstance.client; +}; + +export const isComposioClientAvailable = (): boolean => { + return !!getServerComposioApiKey(); +}; diff --git a/src/libs/klavis/index.ts b/src/libs/klavis/index.ts deleted file mode 100644 index 29d768e64fc..00000000000 --- a/src/libs/klavis/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { KlavisClient } from 'klavis'; - -import { getServerKlavisApiKey } from '@/config/klavis'; - -/** - * Global Klavis Client instance cache (server-side only) - */ -let klavisClientInstance: { apiKey: string; client: KlavisClient } | undefined; - -/** - * Get or create Klavis Client instance (server-side only) - * The instance is cached and reused if the API key hasn't changed - */ -export const getKlavisClient = (): KlavisClient => { - const apiKey = getServerKlavisApiKey(); - - if (!apiKey) { - throw new Error('Klavis API key is not configured on server'); - } - - if (!klavisClientInstance || klavisClientInstance.apiKey !== apiKey) { - klavisClientInstance = { - apiKey, - client: new KlavisClient({ apiKey }), - }; - } - - return klavisClientInstance.client; -}; - -/** - * Check if Klavis client is available (has API key configured) - */ -export const isKlavisClientAvailable = (): boolean => { - return !!getServerKlavisApiKey(); -}; diff --git a/src/libs/next/proxy/define-config.ts b/src/libs/next/proxy/define-config.ts index b38fca3829d..1471ae082e5 100644 --- a/src/libs/next/proxy/define-config.ts +++ b/src/libs/next/proxy/define-config.ts @@ -191,6 +191,10 @@ export function defineConfig() { // version '/api/version', '/api/desktop/(.*)', + // Composio OAuth callback — hit via a cross-site redirect from the provider + // after Composio-managed auth; only renders a popup-closing page, so it must + // not be session-gated. + '/api/composio/oauth/callback', // better auth '/signin', '/signup', diff --git a/src/libs/swr/keys.ts b/src/libs/swr/keys.ts index ad93dfd9392..f99ecad05f1 100644 --- a/src/libs/swr/keys.ts +++ b/src/libs/swr/keys.ts @@ -80,10 +80,18 @@ export const agentKeys = { export const groupKeys = { detail: def('group:detail', (groupId: string) => ['group:detail', groupId]), list: def('group:list', (isLogin: boolean) => ['group:list', isLogin]), + /** Agent picker for the "add member" modal. */ + queryAgents: def('group:queryAgents', () => ['group:queryAgents']), + /** Agent picker for the "create group" modal. */ + queryAgentsForCreate: def('group:queryAgentsForCreate', () => ['group:queryAgentsForCreate']), }; // ---- session ------------------------------------------------------------ export const sessionKeys = { + createSession: def('session:createSession', (groupId: string | undefined) => [ + 'session:createSession', + groupId, + ]), list: def('session:list', (isLogin: boolean | undefined) => ['session:list', isLogin]), search: def('session:search', (keyword?: string) => ['session:search', keyword]), }; @@ -123,6 +131,11 @@ export const agentConfigKeys = { // ---- aiModel ------------------------------------------------------------ export const aiModelKeys = { + disabledModelsPage: def('aiModel:disabledModelsPage', (providerId: string, offset: number) => [ + 'aiModel:disabledModelsPage', + providerId, + offset, + ]), list: def('aiModel:list', (provider: string | undefined) => ['aiModel:list', provider]), }; @@ -159,6 +172,579 @@ export const serverConfigKeys = { get: 'serverConfig:get' as const, }; +// ---- discover (marketplace) --------------------------------------------- +// NOTE: discover/eval/ragEval/knowledgeBase/device/userMemory/agentKnowledge/ +// agentBot/file/chatTool prefixes are deliberately kept OUT of `CACHE_TIERS` +// (see localStorageProvider.ts) so this key-convergence introduces no new +// persistence — they stay memory-only exactly as before. +export const discoverKeys = { + assistantCategories: def('discover:assistantCategories', (locale: string, params: unknown) => [ + 'discover:assistantCategories', + locale, + params, + ]), + assistantDetail: def('discover:assistantDetail', (locale: string, params: unknown) => [ + 'discover:assistantDetail', + locale, + params, + ]), + assistantIdentifiers: def('discover:assistantIdentifiers', (source?: string) => [ + 'discover:assistantIdentifiers', + source, + ]), + assistantList: def('discover:assistantList', (locale: string, params: unknown) => [ + 'discover:assistantList', + locale, + params, + ]), + favoriteAgents: def('discover:favoriteAgents', (userId: number, params?: unknown) => [ + 'discover:favoriteAgents', + userId, + params, + ]), + favoritePlugins: def('discover:favoritePlugins', (userId: number, params?: unknown) => [ + 'discover:favoritePlugins', + userId, + params, + ]), + followCounts: def('discover:followCounts', (userId: number) => ['discover:followCounts', userId]), + followStatus: def('discover:followStatus', (userId: number) => ['discover:followStatus', userId]), + followers: def('discover:followers', (userId: number, params?: unknown) => [ + 'discover:followers', + userId, + params, + ]), + following: def('discover:following', (userId: number, params?: unknown) => [ + 'discover:following', + userId, + params, + ]), + groupAgentCategories: def('discover:groupAgentCategories', (locale: string, params: unknown) => [ + 'discover:groupAgentCategories', + locale, + params, + ]), + groupAgentDetail: def( + 'discover:groupAgentDetail', + (locale: string, identifier: string, version?: string) => [ + 'discover:groupAgentDetail', + locale, + identifier, + version, + ], + ), + groupAgentIdentifiers: def('discover:groupAgentIdentifiers', () => [ + 'discover:groupAgentIdentifiers', + ]), + groupAgentList: def('discover:groupAgentList', (locale: string, params: unknown) => [ + 'discover:groupAgentList', + locale, + params, + ]), + mcpCategories: def('discover:mcpCategories', (locale: string, params: unknown) => [ + 'discover:mcpCategories', + locale, + params, + ]), + mcpDetail: def('discover:mcpDetail', (locale: string, identifier: string, version?: string) => [ + 'discover:mcpDetail', + locale, + identifier, + version, + ]), + mcpList: def('discover:mcpList', (locale: string, params: unknown) => [ + 'discover:mcpList', + locale, + params, + ]), + modelCategories: def('discover:modelCategories', (params: unknown) => [ + 'discover:modelCategories', + params, + ]), + modelDetail: def('discover:modelDetail', (locale: string, identifier: string) => [ + 'discover:modelDetail', + locale, + identifier, + ]), + modelIdentifiers: def('discover:modelIdentifiers', () => ['discover:modelIdentifiers']), + modelList: def('discover:modelList', (locale: string, params: unknown) => [ + 'discover:modelList', + locale, + params, + ]), + pluginCategories: def('discover:pluginCategories', (locale: string, params: unknown) => [ + 'discover:pluginCategories', + locale, + params, + ]), + pluginDetail: def( + 'discover:pluginDetail', + (locale: string, identifier: string, withManifest?: boolean) => [ + 'discover:pluginDetail', + locale, + identifier, + withManifest, + ], + ), + pluginIdentifiers: def('discover:pluginIdentifiers', () => ['discover:pluginIdentifiers']), + pluginList: def('discover:pluginList', (locale: string, params: unknown) => [ + 'discover:pluginList', + locale, + params, + ]), + providerDetail: def('discover:providerDetail', (locale: string, identifier: string) => [ + 'discover:providerDetail', + locale, + identifier, + ]), + providerIdentifiers: def('discover:providerIdentifiers', () => ['discover:providerIdentifiers']), + providerList: def('discover:providerList', (locale: string, params: unknown) => [ + 'discover:providerList', + locale, + params, + ]), + skillCategories: def('discover:skillCategories', (locale: string, params: unknown) => [ + 'discover:skillCategories', + locale, + params, + ]), + skillDetail: def( + 'discover:skillDetail', + (locale: string, identifier: string, version?: string) => [ + 'discover:skillDetail', + locale, + identifier, + version, + ], + ), + skillList: def('discover:skillList', (locale: string, params: unknown) => [ + 'discover:skillList', + locale, + params, + ]), + userProfile: def('discover:userProfile', (locale: string, username: string) => [ + 'discover:userProfile', + locale, + username, + ]), + // -- marketplace detail "related agents" lists (UI) -- + mcpAgents: def('discover:mcpAgents', (identifier: string, page: number) => [ + 'discover:mcpAgents', + identifier, + page, + ]), + skillAgents: def('discover:skillAgents', (identifier: string, page: number) => [ + 'discover:skillAgents', + identifier, + page, + ]), + skillStoreMarketSkills: def( + 'discover:skillStoreMarketSkills', + (locale: string, keywords: string, page: number) => [ + 'discover:skillStoreMarketSkills', + locale, + keywords, + page, + ], + ), +}; + +// ---- agent eval --------------------------------------------------------- +export const evalKeys = { + benchmarkDetail: def('eval:benchmarkDetail', (id: string) => ['eval:benchmarkDetail', id]), + benchmarks: def('eval:benchmarks', () => ['eval:benchmarks']), + datasetDetail: def('eval:datasetDetail', (id: string) => ['eval:datasetDetail', id]), + datasetRuns: def('eval:datasetRuns', (datasetId: string) => ['eval:datasetRuns', datasetId]), + datasets: def('eval:datasets', (benchmarkId: string) => ['eval:datasets', benchmarkId]), + runDetail: def('eval:runDetail', (id: string) => ['eval:runDetail', id]), + runResults: def('eval:runResults', (id: string) => ['eval:runResults', id]), + runs: def('eval:runs', (benchmarkId?: string) => ['eval:runs', benchmarkId]), + testCases: def('eval:testCases', (datasetId: string, limit?: number, offset?: number) => [ + 'eval:testCases', + datasetId, + limit, + offset, + ]), +}; + +// ---- RAG eval ----------------------------------------------------------- +export const ragEvalKeys = { + datasetList: def('ragEval:datasetList', (knowledgeBaseId?: string) => [ + 'ragEval:datasetList', + knowledgeBaseId, + ]), + datasetRecords: def('ragEval:datasetRecords', (datasetId: string) => [ + 'ragEval:datasetRecords', + datasetId, + ]), + evaluationList: def('ragEval:evaluationList', (knowledgeBaseId?: string) => [ + 'ragEval:evaluationList', + knowledgeBaseId, + ]), +}; + +// ---- knowledge base ----------------------------------------------------- +export const knowledgeBaseKeys = { + item: def('knowledgeBase:item', (id: string) => ['knowledgeBase:item', id]), + list: def('knowledgeBase:list', (workspaceId?: string | null) => + workspaceId ? ['knowledgeBase:list', workspaceId] : ['knowledgeBase:list'], + ), +}; + +// ---- device ------------------------------------------------------------- +export const deviceKeys = { + gitAheadBehind: def('device:gitAheadBehind', (deviceId: string, path: string) => [ + 'device:gitAheadBehind', + deviceId, + path, + ]), + gitBranches: def('device:gitBranches', (deviceId: string, path: string) => [ + 'device:gitBranches', + deviceId, + path, + ]), + gitRemoteBranches: def('device:gitRemoteBranches', (deviceId: string, dirPath: string) => [ + 'device:gitRemoteBranches', + deviceId, + dirPath, + ]), + gitReviewPatches: def( + 'device:gitReviewPatches', + (deviceId: string, dirPath: string, mode: string, baseRef: string) => [ + 'device:gitReviewPatches', + deviceId, + dirPath, + mode, + baseRef, + ], + ), + gitInfo: def('device:gitInfo', (deviceId: string, path: string, isGithub: boolean) => [ + 'device:gitInfo', + deviceId, + path, + isGithub, + ]), + gitWorkingTreeStatus: def('device:gitWorkingTreeStatus', (deviceId: string, path: string) => [ + 'device:gitWorkingTreeStatus', + deviceId, + path, + ]), + listDevices: def('device:listDevices', () => ['device:listDevices']), + repoType: def('device:repoType', (path: string) => ['device:repoType', path]), +}; + +// ---- user memory -------------------------------------------------------- +export const userMemoryKeys = { + activities: def('userMemory:activities', (params: unknown) => ['userMemory:activities', params]), + analysisTask: def('userMemory:analysisTask', (taskId?: string) => [ + 'userMemory:analysisTask', + taskId, + ]), + contexts: def('userMemory:contexts', (params: unknown) => ['userMemory:contexts', params]), + experiences: def('userMemory:experiences', (params: unknown) => [ + 'userMemory:experiences', + params, + ]), + /** Injection identities (distinct from the paginated `identityList`). */ + identities: def('userMemory:identities', () => ['userMemory:identities']), + /** Paginated identity list for the memory home views. */ + identityList: def('userMemory:identityList', (params: unknown) => [ + 'userMemory:identityList', + params, + ]), + memoryDetail: def('userMemory:memoryDetail', (layer: string, id: string) => [ + 'userMemory:memoryDetail', + layer, + id, + ]), + persona: def('userMemory:persona', () => ['userMemory:persona']), + preferences: def('userMemory:preferences', (params: unknown) => [ + 'userMemory:preferences', + params, + ]), + retrieve: def('userMemory:retrieve', (cacheKey: string | undefined) => [ + 'userMemory:retrieve', + cacheKey, + ]), + tags: def('userMemory:tags', () => ['userMemory:tags']), + topicMemories: def('userMemory:topicMemories', (topicId: string) => [ + 'userMemory:topicMemories', + topicId, + ]), +}; + +// ---- tool (skills / plugins / builtin / mcp / composio stores) ------------- +export const toolKeys = { + agentSkillDetail: def('tool:agentSkillDetail', (id: string) => ['tool:agentSkillDetail', id]), + agentSkills: def('tool:agentSkills', () => ['tool:agentSkills']), + composioAppTools: def('tool:composioAppTools', (appSlug: string) => [ + 'tool:composioAppTools', + appSlug, + ]), + composioConnections: def('tool:composioConnections', () => ['tool:composioConnections']), + installedPlugins: def('tool:installedPlugins', () => ['tool:installedPlugins']), + lobehubSkillConnections: def('tool:lobehubSkillConnections', () => [ + 'tool:lobehubSkillConnections', + ]), + lobehubSkillTools: def('tool:lobehubSkillTools', (provider: string) => [ + 'tool:lobehubSkillTools', + provider, + ]), + mcpPluginList: def('tool:mcpPluginList', (locale: string, params: unknown) => [ + 'tool:mcpPluginList', + locale, + params, + ]), + uninstalledBuiltins: def('tool:uninstalledBuiltins', (workspaceId: string | null | undefined) => [ + 'tool:uninstalledBuiltins', + workspaceId, + ]), +}; + +// ---- global ------------------------------------------------------------- +export const globalKeys = { + latestVersion: def('global:latestVersion', () => ['global:latestVersion']), + serverVersion: def('global:serverVersion', () => ['global:serverVersion']), + systemStatus: def('global:systemStatus', () => ['global:systemStatus']), +}; + +// ---- agent knowledge (kept off the `agent:` idb tier on purpose) -------- +export const agentKnowledgeKeys = { + list: def('agentKnowledge:list', (agentId: string | undefined) => [ + 'agentKnowledge:list', + agentId, + ]), +}; + +// ---- agent bot ---------------------------------------------------------- +export const agentBotKeys = { + platformDefinitions: def('agentBot:platformDefinitions', () => ['agentBot:platformDefinitions']), + providers: def('agentBot:providers', (agentId: string) => ['agentBot:providers', agentId]), +}; + +// ---- file --------------------------------------------------------------- +export const fileKeys = { + knowledgeItems: def('file:knowledgeItems', (params: unknown) => ['file:knowledgeItems', params]), + ttsFile: def('file:ttsFile', (messageId: string) => ['file:ttsFile', messageId]), +}; + +// ---- chat tools --------------------------------------------------------- +export const chatToolKeys = { + interpreterFile: def('chat:interpreterFile', (id: string) => ['chat:interpreterFile', id]), +}; + +// ========================================================================= +// UI-layer keys (features / routes / components). Same rule as above: every +// prefix below is deliberately kept OUT of `CACHE_TIERS` (memory-only). Names +// avoid colliding with cached prefixes — e.g. share/topicInfo is `share:` not +// `topic:`, portal header is `portal:` not `document:`. +// ========================================================================= + +// ---- stats (settings/stats + user header counts) ------------------------ +export const statsKeys = { + countMessages: def('stats:countMessages', () => ['stats:countMessages']), + countSessions: def('stats:countSessions', () => ['stats:countSessions']), + countTopics: def('stats:countTopics', () => ['stats:countTopics']), + heatmaps: def('stats:heatmaps', (type: string) => ['stats:heatmaps', type]), + maxTaskDuration: def('stats:maxTaskDuration', () => ['stats:maxTaskDuration']), + messages: def('stats:messages', () => ['stats:messages']), + rankAgents: def('stats:rankAgents', () => ['stats:rankAgents']), + rankModels: def('stats:rankModels', () => ['stats:rankModels']), + rankTopics: def('stats:rankTopics', () => ['stats:rankTopics']), + sessions: def('stats:sessions', () => ['stats:sessions']), + topics: def('stats:topics', () => ['stats:topics']), + usageLogs: def('stats:usageLogs', () => ['stats:usageLogs']), + usageStat: def('stats:usageStat', () => ['stats:usageStat']), + welcome: def('stats:welcome', () => ['stats:welcome']), +}; + +// ---- messenger / platform integration ----------------------------------- +export const messengerKeys = { + agentsForBinding: def('messenger:agentsForBinding', (workspaceId: string | null | undefined) => [ + 'messenger:agentsForBinding', + workspaceId ?? null, + ]), + availablePlatforms: def('messenger:availablePlatforms', () => ['messenger:availablePlatforms']), + bindingScopes: def('messenger:bindingScopes', () => ['messenger:bindingScopes']), + listMyInstallations: def('messenger:listMyInstallations', () => [ + 'messenger:listMyInstallations', + ]), + listMyLinks: def('messenger:listMyLinks', () => ['messenger:listMyLinks']), + myLink: def('messenger:myLink', (platform: string, tokenScopeKey: string | undefined) => [ + 'messenger:myLink', + platform, + tokenScopeKey, + ]), + peek: def('messenger:peek', (randomId: string) => ['messenger:peek', randomId]), +}; + +// ---- verify (deliverable judging) --------------------------------------- +export const verifyKeys = { + instruction: def('verify:instruction', (documentId: string) => [ + 'verify:instruction', + documentId, + ]), + results: def('verify:results', (operationId: string) => ['verify:results', operationId]), + rubric: def('verify:rubric', (rubricId: string) => ['verify:rubric', rubricId]), + state: def('verify:state', (operationId: string) => ['verify:state', operationId]), + tracing: def('verify:tracing', (tracingId: string) => ['verify:tracing', tracingId]), +}; + +// ---- inbox / notifications ---------------------------------------------- +export const inboxKeys = { + notifications: def( + 'inbox:notifications', + (cursor: string | undefined, unreadOnly: boolean | undefined) => [ + 'inbox:notifications', + cursor, + unreadOnly, + ], + ), + unreadCount: def('inbox:unreadCount', () => ['inbox:unreadCount']), +}; + +// ---- share (shared topic / page) ---------------------------------------- +export const shareKeys = { + pageDocument: def('share:pageDocument', (documentId: string) => [ + 'share:pageDocument', + documentId, + ]), + topic: def('share:topic', (id: string) => ['share:topic', id]), + topicInfo: def('share:topicInfo', (topicId: string) => ['share:topicInfo', topicId]), +}; + +// ---- fork source (community detail) ------------------------------------- +export const forkKeys = { + groupSource: def('fork:groupSource', (identifier: string) => ['fork:groupSource', identifier]), + source: def('fork:source', (identifier: string) => ['fork:source', identifier]), +}; + +// ---- portal ------------------------------------------------------------- +export const portalKeys = { + documentHeader: def('portal:documentHeader', (documentId: string) => [ + 'portal:documentHeader', + documentId, + ]), +}; + +// ---- favorite status (marketplace detail headers) ----------------------- +export const favoriteKeys = { + status: def('favorite:status', (targetType: string, identifier: string) => [ + 'favorite:status', + targetType, + identifier, + ]), +}; + +// ---- changelog ---------------------------------------------------------- +export const changelogKeys = { + modalIndex: def('changelog:modalIndex', () => ['changelog:modalIndex']), + post: def('changelog:post', (id: string, locale: string) => ['changelog:post', id, locale]), +}; + +// ---- agent onboarding --------------------------------------------------- +export const onboardingKeys = { + agentBootstrap: def('onboarding:agentBootstrap', () => ['onboarding:agentBootstrap']), + agentHistoryTopics: def('onboarding:agentHistoryTopics', (agentId: string) => [ + 'onboarding:agentHistoryTopics', + agentId, + ]), +}; + +// ---- agent home / profile / signal (kept off the `agent:` idb tier) ----- +export const agentHomeKeys = { + topics: def('agentHome:topics', (agentId: string) => ['agentHome:topics', agentId]), +}; +export const agentProfileKeys = { + detail: def('agentProfile:detail', (agentId: string) => ['agentProfile:detail', agentId]), +}; +export const agentSignalKeys = { + receipts: def('agentSignal:receipts', (agentId: string, topicId: string) => [ + 'agentSignal:receipts', + agentId, + topicId, + ]), +}; + +// ---- misc UI singletons ------------------------------------------------- +export const ollamaKeys = { + downloadModel: def('ollama:downloadModel', (model: string) => ['ollama:downloadModel', model]), +}; +export const authKeys = { + oidcInteraction: def('auth:oidcInteraction', (uid: string) => ['auth:oidcInteraction', uid]), +}; +export const cronKeys = { + topicsWithJobInfo: def('cron:topicsWithJobInfo', (agentId: string | undefined) => [ + 'cron:topicsWithJobInfo', + agentId, + ]), +}; +/** Imperative "save / create topic" action (useActionSWR), shared across call sites. */ +export const topicActionKeys = { + openNewOrSave: def('topicAction:openNewOrSave', () => ['topicAction:openNewOrSave']), +}; + +// ---- misc remaining domains (memory-only; off CACHE_TIERS) -------------- +export const homeKeys = { + dailyBrief: def('home:dailyBrief', (userId: string) => ['home:dailyBrief', userId]), +}; +export const taskTemplateKeys = { + listDailyRecommend: def( + 'taskTemplate:listDailyRecommend', + (interestsKey: string, refreshSeed: unknown, recommendationCount: number) => [ + 'taskTemplate:listDailyRecommend', + interestsKey, + refreshSeed, + recommendationCount, + ], + ), +}; +export const resourceKeys = { + list: def('resource:list', (params: unknown, workspaceId: string | null) => [ + 'resource:list', + params, + workspaceId, + ]), + search: def('resource:search', (params: unknown) => ['resource:search', params]), +}; +export const providerKeys = { + clientConfig: def('provider:clientConfig', (id: string) => ['provider:clientConfig', id]), +}; +export const recommendationsKeys = { + heteroDetections: def('recommendations:heteroDetections', () => [ + 'recommendations:heteroDetections', + ]), +}; +export const openInAppKeys = { + detect: def('openInApp:detect', () => ['openInApp:detect']), +}; +export const gatewayKeys = { + reconnect: def('gateway:reconnect', (operationId: string) => ['gateway:reconnect', operationId]), +}; +export const userKeys = { + checkTrace: def('user:checkTrace', () => ['user:checkTrace']), + initState: def('user:initState', () => ['user:initState']), +}; +export const builtinAgentKeys = { + init: def('builtinAgent:init', (slug: string) => ['builtinAgent:init', slug]), +}; +export const imessageKeys = { + bridgeStatus: def('imessage:bridgeStatus', () => ['imessage:bridgeStatus']), +}; +export const sidebarKeys = { + taskGroups: def('sidebar:taskGroups', (agentId: string) => ['sidebar:taskGroups', agentId]), +}; +// Desktop/electron IPC fetches — roots keep their existing `electron:getXxx` value. +export const electronKeys = { + appTrayVisible: def('electron:getAppTrayVisible', () => ['electron:getAppTrayVisible']), + desktopHotkeys: def('electron:getDesktopHotkeys', () => ['electron:getDesktopHotkeys']), + gatewayDeviceInfo: def('electron:getGatewayDeviceInfo', () => ['electron:getGatewayDeviceInfo']), + proxySettings: def('electron:getProxySettings', () => ['electron:getProxySettings']), + remoteServerConfig: def('electron:getRemoteServerConfig', () => [ + 'electron:getRemoteServerConfig', + ]), +}; + /** * Build a `mutate` matcher that selects every key in a `domain:` namespace. * @@ -174,19 +760,60 @@ export const matchDomain = */ export const swrKeys = { agent: { ...agentKeys, ...agentConfigKeys }, + agentBot: agentBotKeys, agentDocument: agentDocumentSWRKeys, + agentHome: agentHomeKeys, + agentKnowledge: agentKnowledgeKeys, + agentProfile: agentProfileKeys, + agentSignal: agentSignalKeys, aiModel: aiModelKeys, + auth: authKeys, brief: briefKeys, + builtinAgent: builtinAgentKeys, + changelog: changelogKeys, + chatTool: chatToolKeys, + cron: cronKeys, + device: deviceKeys, + discover: discoverKeys, document: documentSWRKeys, + electron: electronKeys, + eval: evalKeys, + favorite: favoriteKeys, + file: fileKeys, + fork: forkKeys, + gateway: gatewayKeys, + global: globalKeys, group: groupKeys, + home: homeKeys, image: imageKeys, + imessage: imessageKeys, + inbox: inboxKeys, + knowledgeBase: knowledgeBaseKeys, message: messageKeys, + messenger: messengerKeys, notebook: notebookSWRKeys, + ollama: ollamaKeys, + onboarding: onboardingKeys, + openInApp: openInAppKeys, + portal: portalKeys, + provider: providerKeys, + ragEval: ragEvalKeys, recent: recentKeys, + recommendations: recommendationsKeys, + resource: resourceKeys, serverConfig: serverConfigKeys, session: sessionKeys, + share: shareKeys, + sidebar: sidebarKeys, + stats: statsKeys, task: taskKeys, + taskTemplate: taskTemplateKeys, thread: threadKeys, + tool: toolKeys, topic: topicKeys, + topicAction: topicActionKeys, + user: userKeys, + userMemory: userMemoryKeys, + verify: verifyKeys, video: videoKeys, }; diff --git a/src/routes/(main)/agent/_layout/Sidebar/Header/Nav.tsx b/src/routes/(main)/agent/_layout/Sidebar/Header/Nav.tsx index c489e5f2576..11db751ef02 100644 --- a/src/routes/(main)/agent/_layout/Sidebar/Header/Nav.tsx +++ b/src/routes/(main)/agent/_layout/Sidebar/Header/Nav.tsx @@ -18,6 +18,7 @@ import { usePermission } from '@/hooks/usePermission'; import { useQueryRoute } from '@/hooks/useQueryRoute'; import { usePathname } from '@/libs/router/navigation'; import { useActionSWR } from '@/libs/swr'; +import { topicActionKeys } from '@/libs/swr/keys'; import { useAgentStore } from '@/store/agent'; import { agentSelectors } from '@/store/agent/selectors'; import { useChatStore } from '@/store/chat'; @@ -49,7 +50,7 @@ const Nav = memo(() => { const switchTopic = useChatStore((s) => s.switchTopic); const [openNewTopicOrSaveTopic] = useChatStore((s) => [s.openNewTopicOrSaveTopic]); - const { mutate } = useActionSWR('openNewTopicOrSaveTopic', openNewTopicOrSaveTopic); + const { mutate } = useActionSWR(topicActionKeys.openNewOrSave(), openNewTopicOrSaveTopic); const handleNewTopic = () => { if (!canCreateTopic) return; // Always navigate to the bare agent chat URL — drops any sub-route diff --git a/src/routes/(main)/agent/_layout/Sidebar/Task/index.tsx b/src/routes/(main)/agent/_layout/Sidebar/Task/index.tsx index ad41fc67d95..fb4ab128e61 100644 --- a/src/routes/(main)/agent/_layout/Sidebar/Task/index.tsx +++ b/src/routes/(main)/agent/_layout/Sidebar/Task/index.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'; import SkeletonList from '@/features/NavPanel/components/SkeletonList'; import { useClientDataSWR } from '@/libs/swr'; +import { sidebarKeys } from '@/libs/swr/keys'; import { taskService } from '@/services/task'; import { useAgentStore } from '@/store/agent'; import { agentSelectors } from '@/store/agent/selectors'; @@ -20,8 +21,6 @@ const SIDEBAR_GROUPS = [ ]; const STATUS_ORDER = SIDEBAR_GROUPS.map((g) => g.key); -const FETCH_SIDEBAR_TASK_GROUPS_KEY = 'fetchSidebarTaskGroups'; - interface TaskListProps { itemKey: string; } @@ -33,7 +32,7 @@ const TaskList = memo(({ itemKey }) => { const enabled = !isHeterogeneous && !!agentId; const { data, isLoading } = useClientDataSWR<{ data: TaskGroupItem[]; success: boolean }>( - enabled ? [FETCH_SIDEBAR_TASK_GROUPS_KEY, agentId] : null, + enabled ? sidebarKeys.taskGroups(agentId) : null, async ([, id]: [string, string]) => taskService.groupList({ assigneeAgentId: id, groups: SIDEBAR_GROUPS }), { diff --git a/src/routes/(main)/agent/channel/platform/imessage/CredentialExtras.tsx b/src/routes/(main)/agent/channel/platform/imessage/CredentialExtras.tsx index a520c7c35ab..7fe78013d6c 100644 --- a/src/routes/(main)/agent/channel/platform/imessage/CredentialExtras.tsx +++ b/src/routes/(main)/agent/channel/platform/imessage/CredentialExtras.tsx @@ -11,6 +11,7 @@ import { useTranslation } from 'react-i18next'; import { FormInput, FormPassword } from '@/components/FormInput'; import { useClientDataSWR } from '@/libs/swr'; +import { imessageKeys } from '@/libs/swr/keys'; import { gatewayConnectionService } from '@/services/electron/gatewayConnection'; import { imessageBridgeService } from '@/services/electron/imessageBridge'; @@ -65,8 +66,6 @@ type TestStatus = 'idle' | 'success' | 'failed'; const BLUEBUBBLES_ICON_URL = 'https://bluebubbles.app/web/splash/img/light-2x.png'; -const BRIDGE_STATUS_KEY = 'imessage-bridge-status'; - const getErrorMessage = (error: unknown) => error instanceof Error ? error.message : String(error); @@ -83,7 +82,7 @@ const CredentialExtras = memo(() => { // it through SWR (revalidates on focus + after each mutation) instead of // caching a copy that can drift — so there's no manual Refresh to keep in sync. const { data: status, mutate } = useClientDataSWR( - isDesktop ? BRIDGE_STATUS_KEY : null, + isDesktop ? imessageKeys.bridgeStatus() : null, () => imessageBridgeService.getStatus(), ); diff --git a/src/routes/(main)/agent/features/Conversation/AgentWelcome/OpeningQuestions.tsx b/src/routes/(main)/agent/features/Conversation/AgentWelcome/OpeningQuestions.tsx deleted file mode 100644 index 14861d38592..00000000000 --- a/src/routes/(main)/agent/features/Conversation/AgentWelcome/OpeningQuestions.tsx +++ /dev/null @@ -1,67 +0,0 @@ -'use client'; - -import { Block, Flexbox } from '@lobehub/ui'; -import { createStaticStyles, responsive } from 'antd-style'; -import { memo } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { useConversationStore } from '@/features/Conversation'; - -const styles = createStaticStyles(({ css, cssVar }) => ({ - card: css` - padding-block: 8px; - padding-inline: 16px; - border-radius: 48px; - - ${responsive.sm} { - padding-block: 8px; - padding-inline: 16px; - } - `, - - container: css` - padding-block: 0; - padding-inline: 0; - `, - - title: css` - color: ${cssVar.colorTextDescription}; - `, -})); - -interface OpeningQuestionsProps { - mobile?: boolean; - questions: string[]; -} - -const OpeningQuestions = memo(({ mobile, questions }) => { - const { t } = useTranslation('welcome'); - const [sendMessage] = useConversationStore((s) => [s.sendMessage]); - - return ( -
-

{t('guide.questions.title')}

- - {questions.slice(0, mobile ? 2 : 5).map((question) => { - return ( - { - sendMessage({ message: question }); - }} - > - {question} - - ); - })} - -
- ); -}); - -export default OpeningQuestions; diff --git a/src/routes/(main)/agent/features/Conversation/AgentWelcome/ToolAuthAlert.tsx b/src/routes/(main)/agent/features/Conversation/AgentWelcome/ToolAuthAlert.tsx index 509b69b611d..d3628cd6b0c 100644 --- a/src/routes/(main)/agent/features/Conversation/AgentWelcome/ToolAuthAlert.tsx +++ b/src/routes/(main)/agent/features/Conversation/AgentWelcome/ToolAuthAlert.tsx @@ -1,7 +1,7 @@ 'use client'; -import { type KlavisServerType } from '@lobechat/const'; -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { Alert, Avatar, Button, Flexbox, Icon, Text } from '@lobehub/ui'; import { Divider } from 'antd'; import { cssVar } from 'antd-style'; @@ -14,8 +14,8 @@ import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth'; import { useAgentStore } from '@/store/agent'; import { agentSelectors } from '@/store/agent/selectors'; import { useToolStore } from '@/store/tool'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { KlavisServerStatus, klavisStoreSelectors } from '@/store/tool/slices/klavisStore'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; +import { ComposioServerStatus, composioStoreSelectors } from '@/store/tool/slices/composioStore'; import { useUserStore } from '@/store/user'; import { userProfileSelectors } from '@/store/user/selectors'; @@ -31,9 +31,9 @@ const MARKET_AUTH_TOOLS = [ const POLL_INTERVAL_MS = 1000; const POLL_TIMEOUT_MS = 15_000; -interface PendingKlavisTool extends KlavisServerType { - authType: 'klavis'; - server?: KlavisServer; +interface PendingComposioTool extends ComposioAppType { + authType: 'composio'; + server?: ComposioServer; } interface PendingMarketTool { @@ -43,14 +43,14 @@ interface PendingMarketTool { label: string; } -type PendingAuthTool = PendingKlavisTool | PendingMarketTool; +type PendingAuthTool = PendingComposioTool | PendingMarketTool; -interface KlavisToolAuthItemProps { +interface ComposioToolAuthItemProps { onAuthComplete: () => void; - tool: PendingKlavisTool; + tool: PendingComposioTool; } -const KlavisToolAuthItem = memo(({ tool, onAuthComplete }) => { +const ComposioToolAuthItem = memo(({ tool, onAuthComplete }) => { const { t } = useTranslation('chat'); const [isConnecting, setIsConnecting] = useState(false); const [isWaitingAuth, setIsWaitingAuth] = useState(false); @@ -61,8 +61,8 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete const pollTimeoutRef = useRef | null>(null); const userId = useUserStore(userProfileSelectors.userId); - const createKlavisServer = useToolStore((s) => s.createKlavisServer); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); + const createComposioConnection = useToolStore((s) => s.createComposioConnection); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); const cleanup = useCallback(() => { if (windowCheckIntervalRef.current) { @@ -88,7 +88,7 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete }, [cleanup]); useEffect(() => { - if (tool.server?.status === KlavisServerStatus.CONNECTED && isWaitingAuth) { + if (tool.server?.status === ComposioServerStatus.ACTIVE && isWaitingAuth) { cleanup(); onAuthComplete(); } @@ -100,9 +100,9 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete pollIntervalRef.current = setInterval(async () => { try { - await refreshKlavisServerTools(identifier); + await refreshComposioConnectionStatus(identifier); } catch (error) { - console.info('[Klavis] Polling check (expected during auth):', error); + console.info('[Composio] Polling check (expected during auth):', error); } }, POLL_INTERVAL_MS); @@ -114,7 +114,7 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete setIsWaitingAuth(false); }, POLL_TIMEOUT_MS); }, - [refreshKlavisServerTools], + [refreshComposioConnectionStatus], ); const startWindowMonitor = useCallback( @@ -139,15 +139,15 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete } }, 500); }, - [refreshKlavisServerTools, startFallbackPolling], + [refreshComposioConnectionStatus, startFallbackPolling], ); const openOAuthWindow = useCallback( - (oauthUrl: string, identifier: string) => { + (redirectUrl: string, identifier: string) => { cleanup(); setIsWaitingAuth(true); - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; startWindowMonitor(oauthWindow, identifier); @@ -161,25 +161,25 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete const handleAuthorize = async () => { if (!userId) return; - if (tool.server?.status === KlavisServerStatus.PENDING_AUTH && tool.server.oauthUrl) { - openOAuthWindow(tool.server.oauthUrl, tool.server.identifier); + if (tool.server?.status === ComposioServerStatus.PENDING_AUTH && tool.server.redirectUrl) { + openOAuthWindow(tool.server.redirectUrl, tool.server.identifier); return; } setIsConnecting(true); try { - const newServer = await createKlavisServer({ + const newServer = await createComposioConnection({ + appSlug: tool.appSlug, identifier: tool.identifier, - serverName: tool.serverName, - userId, + label: tool.label, }); if (newServer) { - if (newServer.isAuthenticated) { - await refreshKlavisServerTools(newServer.identifier); + if (newServer.status === ComposioServerStatus.ACTIVE) { + await refreshComposioConnectionStatus(newServer.identifier); onAuthComplete(); - } else if (newServer.oauthUrl) { - openOAuthWindow(newServer.oauthUrl, newServer.identifier); + } else if (newServer.redirectUrl) { + openOAuthWindow(newServer.redirectUrl, newServer.identifier); } } } catch (error) { @@ -227,7 +227,7 @@ const KlavisToolAuthItem = memo(({ tool, onAuthComplete ); }); -KlavisToolAuthItem.displayName = 'KlavisToolAuthItem'; +ComposioToolAuthItem.displayName = 'ComposioToolAuthItem'; interface MarketToolAuthItemProps { tool: PendingMarketTool; @@ -280,7 +280,7 @@ const ToolAuthAlert = memo(() => { const { t } = useTranslation('chat'); const plugins = useAgentStore(agentSelectors.currentAgentPlugins, isEqual); - const klavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); + const composioServers = useToolStore(composioStoreSelectors.getServers, isEqual); const { isAuthenticated: isMarketAuthenticated } = useMarketAuth(); // Filter out tools that need authorization @@ -288,13 +288,13 @@ const ToolAuthAlert = memo(() => { const result: PendingAuthTool[] = []; for (const pluginId of plugins) { - // Check if this is a Klavis tool - const klavisType = KLAVIS_SERVER_TYPES.find((t) => t.identifier === pluginId); - if (klavisType) { - const server = klavisServers.find((s) => s.identifier === pluginId); + // Check if this is a Composio tool + const composioType = COMPOSIO_APP_TYPES.find((t) => t.identifier === pluginId); + if (composioType) { + const server = composioServers.find((s) => s.identifier === pluginId); // Not installed or pending auth - if (!server || server.status === KlavisServerStatus.PENDING_AUTH) { - result.push({ ...klavisType, authType: 'klavis', server }); + if (!server || server.status === ComposioServerStatus.PENDING_AUTH) { + result.push({ ...composioType, authType: 'composio', server }); } continue; } @@ -307,7 +307,7 @@ const ToolAuthAlert = memo(() => { } return result; - }, [plugins, klavisServers, isMarketAuthenticated]); + }, [plugins, composioServers, isMarketAuthenticated]); // Don't render if no pending auth tools if (pendingAuthTools.length === 0) { @@ -325,8 +325,8 @@ const ToolAuthAlert = memo(() => { {pendingAuthTools.map((tool) => - tool.authType === 'klavis' ? ( - { diff --git a/src/routes/(main)/agent/features/Conversation/AgentWelcome/index.tsx b/src/routes/(main)/agent/features/Conversation/AgentWelcome/index.tsx deleted file mode 100644 index a14e684360d..00000000000 --- a/src/routes/(main)/agent/features/Conversation/AgentWelcome/index.tsx +++ /dev/null @@ -1,73 +0,0 @@ -'use client'; - -import { Avatar, Flexbox, Markdown, Text } from '@lobehub/ui'; -import isEqual from 'fast-deep-equal'; -import React, { memo, useMemo } from 'react'; -import { useTranslation } from 'react-i18next'; - -import { DEFAULT_AVATAR, DEFAULT_INBOX_AVATAR } from '@/const/meta'; -import { useIsMobile } from '@/hooks/useIsMobile'; -import { useAgentStore } from '@/store/agent'; -import { agentSelectors, builtinAgentSelectors } from '@/store/agent/selectors'; -import { useUserStore } from '@/store/user'; -import { userGeneralSettingsSelectors } from '@/store/user/selectors'; - -import OpeningQuestions from './OpeningQuestions'; -import ToolAuthAlert from './ToolAuthAlert'; - -const InboxWelcome = memo(() => { - const { t } = useTranslation(['welcome', 'chat']); - const mobile = useIsMobile(); - const isInbox = useAgentStore(builtinAgentSelectors.isInboxAgent); - const openingQuestions = useAgentStore(agentSelectors.openingQuestions, isEqual); - const fontSize = useUserStore(userGeneralSettingsSelectors.fontSize); - const meta = useAgentStore(agentSelectors.currentAgentMeta, isEqual); - - const agentSystemRoleMsg = t('agentDefaultMessageWithSystemRole', { - name: meta.title || t('defaultAgent', { ns: 'chat' }), - ns: 'chat', - }); - const openingMessage = useAgentStore(agentSelectors.openingMessage); - - const message = useMemo(() => { - if (openingMessage) return openingMessage; - return agentSystemRoleMsg; - }, [openingMessage, agentSystemRoleMsg, meta.description]); - - const inboxTitle = meta.title || 'Lobe AI'; - const displayTitle = isInbox ? inboxTitle : meta.title || t('defaultSession', { ns: 'common' }); - - return ( - <> - - - - - {displayTitle} - - - - {isInbox ? t('guide.defaultMessageWithoutCreate', { appName: inboxTitle }) : message} - - - {openingQuestions.length > 0 && ( - - )} - - - - ); -}); - -export default InboxWelcome; diff --git a/src/routes/(main)/agent/features/Conversation/WorkingSidebar/Review/useReviewPatches.ts b/src/routes/(main)/agent/features/Conversation/WorkingSidebar/Review/useReviewPatches.ts index b13f032f3f2..b3684d770e8 100644 --- a/src/routes/(main)/agent/features/Conversation/WorkingSidebar/Review/useReviewPatches.ts +++ b/src/routes/(main)/agent/features/Conversation/WorkingSidebar/Review/useReviewPatches.ts @@ -4,6 +4,7 @@ import type { } from '@lobechat/electron-client-ipc'; import { useClientDataSWR } from '@/libs/swr'; +import { deviceKeys } from '@/libs/swr/keys'; import { gitService } from '@/services/git'; export type ReviewMode = 'unstaged' | 'branch'; @@ -62,7 +63,7 @@ export const useReviewPatches = ( ) => { const enabled = Boolean(dirPath); const key = enabled - ? ['git-review-patches', deviceId ?? 'local', dirPath, mode, baseRef ?? ''] + ? deviceKeys.gitReviewPatches(deviceId ?? 'local', dirPath!, mode, baseRef ?? '') : null; return useClientDataSWR( @@ -90,7 +91,8 @@ export const useGitRemoteBranches = ( enabled: boolean, deviceId?: string, ) => { - const key = dirPath && enabled ? ['git-remote-branches', deviceId ?? 'local', dirPath] : null; + const key = + dirPath && enabled ? deviceKeys.gitRemoteBranches(deviceId ?? 'local', dirPath) : null; return useClientDataSWR( key, () => gitService.listGitRemoteBranches({ deviceId, path: dirPath! }), diff --git a/src/routes/(main)/agent/profile/features/Header/index.test.tsx b/src/routes/(main)/agent/profile/features/Header/index.test.tsx index 3acda84f5cf..94cf57e56cd 100644 --- a/src/routes/(main)/agent/profile/features/Header/index.test.tsx +++ b/src/routes/(main)/agent/profile/features/Header/index.test.tsx @@ -30,7 +30,7 @@ const mocks = vi.hoisted(() => ({ removeAgent: vi.fn(), }, marketAuth: { - isAuthenticated: true, + status: 'ACTIVE', isLoading: false, signIn: vi.fn(), }, diff --git a/src/routes/(main)/agent/profile/features/ProfileEditor/MentionList/useMentionItems.tsx b/src/routes/(main)/agent/profile/features/ProfileEditor/MentionList/useMentionItems.tsx index b41d6a6ebd6..0842c32de34 100644 --- a/src/routes/(main)/agent/profile/features/ProfileEditor/MentionList/useMentionItems.tsx +++ b/src/routes/(main)/agent/profile/features/ProfileEditor/MentionList/useMentionItems.tsx @@ -1,5 +1,5 @@ -import { type KlavisServerType } from '@lobechat/const'; -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { ToolNameResolver } from '@lobechat/context-engine'; import { type API } from '@lobechat/prompts'; import { apiPrompt, toolPrompt } from '@lobechat/prompts'; @@ -22,16 +22,16 @@ import { hydrationPrompt } from '@/utils/promptTemplate'; import MentionDropdown from './MentionDropdown'; import { type MentionListOption, type MentionMetadata } from './types'; -// Get Klavis server type config by identifier -const getKlavisServerType = (identifier: string) => - KLAVIS_SERVER_TYPES.find((type) => type.identifier === identifier); +// Get Composio server type config by identifier +const getComposioAppType = (identifier: string) => + COMPOSIO_APP_TYPES.find((type) => type.identifier === identifier); /** - * Klavis server icon component + * Composio server icon component * For string type icon, renders using Image component * For IconType type icon, renders using Icon component and sets fill color based on theme */ -const KlavisIcon = memo>(({ icon, label }) => { +const ComposioIcon = memo>(({ icon, label }) => { if (typeof icon === 'string') { return {label}; } @@ -135,10 +135,10 @@ const useMentionOptions = () => { type: 'collection', }); - // Prefer Klavis icon, fall back to PluginAvatar - const klavisServerType = getKlavisServerType(tool.identifier); - const icon = klavisServerType ? ( - + // Prefer Composio icon, fall back to PluginAvatar + const composioServerType = getComposioAppType(tool.identifier); + const icon = composioServerType ? ( + ) : ( ); diff --git a/src/routes/(main)/community/(detail)/agent/features/AgentForkTag.tsx b/src/routes/(main)/community/(detail)/agent/features/AgentForkTag.tsx index 6097c63543c..1614fbe36ba 100644 --- a/src/routes/(main)/community/(detail)/agent/features/AgentForkTag.tsx +++ b/src/routes/(main)/community/(detail)/agent/features/AgentForkTag.tsx @@ -8,6 +8,7 @@ import useSWR from 'swr'; import urlJoin from 'url-join'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; +import { forkKeys } from '@/libs/swr/keys'; import { marketApiService } from '@/services/marketApi'; import { useDetailContext } from './DetailProvider'; @@ -23,7 +24,7 @@ const AgentForkTag = memo(() => { // Fetch fork source info const { data: forkSource } = useSWR( - identifier && forkedFromAgentId ? ['fork-source', identifier] : null, + identifier && forkedFromAgentId ? forkKeys.source(identifier) : null, () => marketApiService.getAgentForkSource(identifier!), { revalidateOnFocus: false }, ); diff --git a/src/routes/(main)/community/(detail)/agent/features/Details/Capabilities/PluginItem.tsx b/src/routes/(main)/community/(detail)/agent/features/Details/Capabilities/PluginItem.tsx index c2f8d3689df..8bb5ed4ffea 100644 --- a/src/routes/(main)/community/(detail)/agent/features/Details/Capabilities/PluginItem.tsx +++ b/src/routes/(main)/community/(detail)/agent/features/Details/Capabilities/PluginItem.tsx @@ -1,8 +1,8 @@ import { builtinTools } from '@lobechat/builtin-tools'; import { + COMPOSIO_APP_TYPES, + type ComposioAppType, getLobehubSkillProviderById, - KLAVIS_SERVER_TYPES, - type KlavisServerType, type LobehubSkillProviderType, } from '@lobechat/const'; import { type DiscoverPluginDetail, type PluginSource } from '@lobechat/types'; @@ -16,11 +16,11 @@ import WorkspaceLink from '@/features/Workspace/WorkspaceLink'; import { useDiscoverStore } from '@/store/discover'; /** - * Icon component for built-in tools (Klavis & LobehubSkill) + * Icon component for built-in tools (Composio & LobehubSkill) * For string type icon, use Image component to render * For IconType type icon, use Icon component to render with theme fill color */ -const BuiltinToolIcon = memo>( +const BuiltinToolIcon = memo>( ({ icon, label }) => { if (typeof icon === 'string') { return {label}; @@ -78,9 +78,9 @@ const PluginItem = memo(({ identifier }) => { const usePluginDetail = useDiscoverStore((s) => s.usePluginDetail); const { data: apiData, isLoading } = usePluginDetail({ identifier, withManifest: false }); - // Try to get Klavis tool info if API returns no data - const klavisTool = useMemo(() => { - return KLAVIS_SERVER_TYPES.find((tool) => tool.identifier === identifier); + // Try to get Composio tool info if API returns no data + const composioTool = useMemo(() => { + return COMPOSIO_APP_TYPES.find((tool) => tool.identifier === identifier); }, [identifier]); // Try to get LobehubSkill info if API returns no data @@ -97,22 +97,22 @@ const PluginItem = memo(({ identifier }) => { const data: DiscoverPluginDetail | undefined = useMemo(() => { if (apiData) return apiData; - // Check Klavis tools - if (klavisTool) { + // Check Composio tools + if (composioTool) { return { - author: 'Klavis', + author: 'Composio', avatar: '', // Avatar will be rendered by BuiltinToolIcon component category: undefined, createdAt: '', - description: `LobeHub Mcp Server: ${klavisTool.label}`, - homepage: 'https://klavis.ai', - identifier: klavisTool.identifier, + description: `LobeHub Mcp Server: ${composioTool.label}`, + homepage: 'https://composio.dev', + identifier: composioTool.identifier, manifest: undefined, related: [], schemaVersion: 1, source: 'builtin' as const, - tags: ['klavis', 'mcp'], - title: klavisTool.label, + tags: ['composio', 'mcp'], + title: composioTool.label, }; } @@ -155,7 +155,7 @@ const PluginItem = memo(({ identifier }) => { } return undefined; - }, [apiData, klavisTool, lobehubSkill, builtinTool]); + }, [apiData, composioTool, lobehubSkill, builtinTool]); const sourceConfig = useMemo(() => { const source: PluginSource = data?.source || 'market'; @@ -205,8 +205,8 @@ const PluginItem = memo(({ identifier }) => { // Render avatar - use BuiltinToolIcon for built-in tools, Avatar for others const renderAvatar = () => { - if (klavisTool) { - return ; + if (composioTool) { + return ; } if (lobehubSkill) { return ; diff --git a/src/routes/(main)/community/(detail)/agent/features/Header.tsx b/src/routes/(main)/community/(detail)/agent/features/Header.tsx index 60f45d075ca..8a039082b8a 100644 --- a/src/routes/(main)/community/(detail)/agent/features/Header.tsx +++ b/src/routes/(main)/community/(detail)/agent/features/Header.tsx @@ -30,6 +30,7 @@ import useSWR from 'swr'; import PublishedTime from '@/components/PublishedTime'; import WorkspaceLink from '@/features/Workspace/WorkspaceLink'; import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth'; +import { favoriteKeys } from '@/libs/swr/keys'; import { socialService } from '@/services/social'; import { formatIntergerNumber } from '@/utils/format'; @@ -73,7 +74,7 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => { // Fetch favorite status const { data: favoriteStatus, mutate: mutateFavorite } = useSWR( - identifier && isAuthenticated ? ['favorite-status', 'agent', identifier] : null, + identifier && isAuthenticated ? favoriteKeys.status('agent', identifier) : null, () => socialService.checkFavoriteStatus('agent', identifier!), { revalidateOnFocus: false }, ); diff --git a/src/routes/(main)/community/(detail)/group_agent/features/GroupAgentForkTag.tsx b/src/routes/(main)/community/(detail)/group_agent/features/GroupAgentForkTag.tsx index e0c97d72a99..5c600e7e2fd 100644 --- a/src/routes/(main)/community/(detail)/group_agent/features/GroupAgentForkTag.tsx +++ b/src/routes/(main)/community/(detail)/group_agent/features/GroupAgentForkTag.tsx @@ -8,6 +8,7 @@ import useSWR from 'swr'; import urlJoin from 'url-join'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; +import { forkKeys } from '@/libs/swr/keys'; import { marketApiService } from '@/services/marketApi'; import { useDetailContext } from './DetailProvider'; @@ -23,7 +24,7 @@ const GroupAgentForkTag = memo(() => { // Fetch fork source info const { data: forkSource } = useSWR( - identifier && forkedFromGroupId ? ['group-fork-source', identifier] : null, + identifier && forkedFromGroupId ? forkKeys.groupSource(identifier) : null, () => marketApiService.getAgentGroupForkSource(identifier!), { revalidateOnFocus: false }, ); diff --git a/src/routes/(main)/community/(detail)/group_agent/features/Header.tsx b/src/routes/(main)/community/(detail)/group_agent/features/Header.tsx index d48c7d8fd5d..40ad52a0d65 100644 --- a/src/routes/(main)/community/(detail)/group_agent/features/Header.tsx +++ b/src/routes/(main)/community/(detail)/group_agent/features/Header.tsx @@ -22,6 +22,7 @@ import useSWR from 'swr'; import PublishedTime from '@/components/PublishedTime'; import WorkspaceLink from '@/features/Workspace/WorkspaceLink'; import { useMarketAuth } from '@/layout/AuthProvider/MarketAuth'; +import { favoriteKeys } from '@/libs/swr/keys'; import { socialService } from '@/services/social'; import { resolveCommunityProfileLink } from '../../utils/profileLink'; @@ -67,7 +68,7 @@ const Header = memo<{ mobile?: boolean }>(({ mobile: isMobile }) => { // TODO: Use 'group_agent' type when social service supports it // Fetch favorite status const { data: favoriteStatus, mutate: mutateFavorite } = useSWR( - identifier && isAuthenticated ? ['favorite-status', 'agent', identifier] : null, + identifier && isAuthenticated ? favoriteKeys.status('agent', identifier) : null, () => socialService.checkFavoriteStatus('agent-group', identifier!), { revalidateOnFocus: false }, ); diff --git a/src/routes/(main)/group/_layout/Sidebar/AddGroupMemberModal/index.tsx b/src/routes/(main)/group/_layout/Sidebar/AddGroupMemberModal/index.tsx index 50de321f11f..94269ed9ef2 100644 --- a/src/routes/(main)/group/_layout/Sidebar/AddGroupMemberModal/index.tsx +++ b/src/routes/(main)/group/_layout/Sidebar/AddGroupMemberModal/index.tsx @@ -7,6 +7,7 @@ import { memo, useEffect, useMemo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import useSWR from 'swr'; +import { groupKeys } from '@/libs/swr/keys'; import { agentService } from '@/services/agent'; import { type AgentItemData } from './AgentItem'; @@ -48,7 +49,7 @@ const AddGroupMemberModal = memo( // Fetch agents from the new API (non-virtual agents only) const { data: allAgents = [], isLoading: isLoadingAgents } = useSWR( - open ? 'queryAgents' : null, + open ? groupKeys.queryAgents() : null, () => agentService.queryAgents(), ); diff --git a/src/routes/(main)/group/profile/features/MemberProfile/MentionList/useMentionItems.tsx b/src/routes/(main)/group/profile/features/MemberProfile/MentionList/useMentionItems.tsx index 804de1fd0ef..b68ffbe5906 100644 --- a/src/routes/(main)/group/profile/features/MemberProfile/MentionList/useMentionItems.tsx +++ b/src/routes/(main)/group/profile/features/MemberProfile/MentionList/useMentionItems.tsx @@ -1,5 +1,5 @@ -import { type KlavisServerType } from '@lobechat/const'; -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { ToolNameResolver } from '@lobechat/context-engine'; import { type API } from '@lobechat/prompts'; import { apiPrompt, toolPrompt } from '@lobechat/prompts'; @@ -22,16 +22,16 @@ import { hydrationPrompt } from '@/utils/promptTemplate'; import MentionDropdown from './MentionDropdown'; import { type MentionListOption, type MentionMetadata } from './types'; -// Get Klavis server type config by identifier -const getKlavisServerType = (identifier: string) => - KLAVIS_SERVER_TYPES.find((type) => type.identifier === identifier); +// Get Composio server type config by identifier +const getComposioAppType = (identifier: string) => + COMPOSIO_APP_TYPES.find((type) => type.identifier === identifier); /** - * Klavis server icon component + * Composio server icon component * For string type icon, renders using Image component * For IconType type icon, renders using Icon component and sets fill color based on theme */ -const KlavisIcon = memo>(({ icon, label }) => { +const ComposioIcon = memo>(({ icon, label }) => { if (typeof icon === 'string') { return {label}; } @@ -135,10 +135,10 @@ const useMentionOptions = () => { type: 'collection', }); - // Prefer Klavis icon, fall back to PluginAvatar - const klavisServerType = getKlavisServerType(tool.identifier); - const icon = klavisServerType ? ( - + // Prefer Composio icon, fall back to PluginAvatar + const composioServerType = getComposioAppType(tool.identifier); + const icon = composioServerType ? ( + ) : ( ); diff --git a/src/routes/(main)/home/_layout/CreateGroupModal/index.tsx b/src/routes/(main)/home/_layout/CreateGroupModal/index.tsx index f92507dd8fe..1f47358fd65 100644 --- a/src/routes/(main)/home/_layout/CreateGroupModal/index.tsx +++ b/src/routes/(main)/home/_layout/CreateGroupModal/index.tsx @@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next'; import useSWR from 'swr'; import { usePermission } from '@/hooks/usePermission'; +import { groupKeys } from '@/libs/swr/keys'; import { agentService } from '@/services/agent'; import { useGlobalStore } from '@/store/global'; import { useHomeStore } from '@/store/home'; @@ -56,7 +57,7 @@ const CreateGroupModal = memo(({ id, onCancel, open }) => // Fetch all agents const { data: allAgents = [], isLoading: isLoadingAgents } = useSWR( - open ? 'queryAgentsForCreateGroup' : null, + open ? groupKeys.queryAgentsForCreate() : null, () => agentService.queryAgents(), ); diff --git a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/Content.tsx b/src/routes/(main)/home/_layout/Header/components/InboxDrawer/Content.tsx index 9d42bd78ed4..fa94a730519 100644 --- a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/Content.tsx +++ b/src/routes/(main)/home/_layout/Header/components/InboxDrawer/Content.tsx @@ -9,9 +9,9 @@ import useSWRInfinite from 'swr/infinite'; import { VList, type VListHandle } from 'virtua'; import SkeletonList from '@/features/NavPanel/components/SkeletonList'; +import { inboxKeys } from '@/libs/swr/keys'; import { notificationService } from '@/services/notification'; -import { FETCH_KEY } from './constants'; import NotificationItem from './NotificationItem'; const PAGE_SIZE = 20; @@ -32,10 +32,10 @@ const Content = memo(({ open, unreadOnly, onMarkAsRead, onArchive if (!open) return null; if (previousPageData && previousPageData.length < PAGE_SIZE) return null; - if (pageIndex === 0) return [FETCH_KEY, undefined, unreadOnly] as const; + if (pageIndex === 0) return inboxKeys.notifications(undefined, unreadOnly); const lastItem = previousPageData?.at(-1); - return [FETCH_KEY, lastItem?.id, unreadOnly] as const; + return inboxKeys.notifications(lastItem?.id, unreadOnly); }, [open, unreadOnly], ); @@ -49,7 +49,7 @@ const Content = memo(({ open, unreadOnly, onMarkAsRead, onArchive return notificationService.list({ cursor: cursor as string | undefined, limit: PAGE_SIZE, - unreadOnly: filterUnread, + unreadOnly: filterUnread as boolean | undefined, }); }); diff --git a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/constants.ts b/src/routes/(main)/home/_layout/Header/components/InboxDrawer/constants.ts deleted file mode 100644 index f7bed4866b1..00000000000 --- a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/constants.ts +++ /dev/null @@ -1,2 +0,0 @@ -export const UNREAD_COUNT_KEY = 'inbox-unread-count'; -export const FETCH_KEY = 'inbox-notifications'; diff --git a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/index.tsx b/src/routes/(main)/home/_layout/Header/components/InboxDrawer/index.tsx index 052c569fc60..b40ef5f385f 100644 --- a/src/routes/(main)/home/_layout/Header/components/InboxDrawer/index.tsx +++ b/src/routes/(main)/home/_layout/Header/components/InboxDrawer/index.tsx @@ -10,10 +10,9 @@ import SkeletonList from '@/features/NavPanel/components/SkeletonList'; import SideBarDrawer from '@/features/NavPanel/SideBarDrawer'; import dynamic from '@/libs/next/dynamic'; import { mutate } from '@/libs/swr'; +import { inboxKeys } from '@/libs/swr/keys'; import { notificationService } from '@/services/notification'; -import { FETCH_KEY, UNREAD_COUNT_KEY } from './constants'; - const Content = dynamic(() => import('./Content'), { loading: () => ( @@ -33,8 +32,8 @@ const InboxDrawer = memo(({ open, onClose }) => { const [unreadOnly, setUnreadOnly] = useState(false); const refreshList = useCallback(() => { - mutate((key: unknown) => Array.isArray(key) && key[0] === FETCH_KEY); - mutate(UNREAD_COUNT_KEY); + mutate((key: unknown) => Array.isArray(key) && key[0] === inboxKeys.notifications.root); + mutate(inboxKeys.unreadCount()); }, []); const handleMarkAsRead = useCallback( diff --git a/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.test.ts b/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.test.ts index dafb08b0dbe..5f37c687507 100644 --- a/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.test.ts +++ b/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.test.ts @@ -1,7 +1,8 @@ import { renderHook } from '@testing-library/react'; import { beforeEach, describe, expect, it, vi } from 'vitest'; -import { UNREAD_COUNT_KEY } from './InboxDrawer/constants'; +import { inboxKeys } from '@/libs/swr/keys'; + import { INBOX_UNREAD_COUNT_REFRESH_INTERVAL, useInboxUnreadCount } from './useInboxUnreadCount'; const mocks = vi.hoisted(() => ({ @@ -66,9 +67,13 @@ describe('useInboxUnreadCount', () => { const { result } = renderHook(() => useInboxUnreadCount()); expect(result.current.enabled).toBe(true); - expect(mocks.useClientDataSWR).toHaveBeenCalledWith(UNREAD_COUNT_KEY, expect.any(Function), { - refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL, - }); + expect(mocks.useClientDataSWR).toHaveBeenCalledWith( + inboxKeys.unreadCount(), + expect.any(Function), + { + refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL, + }, + ); }); it('keeps unread count polling on the same 10 second cadence', () => { diff --git a/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.ts b/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.ts index 1a1747cea17..53f25e2a06c 100644 --- a/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.ts +++ b/src/routes/(main)/home/_layout/Header/components/useInboxUnreadCount.ts @@ -1,11 +1,10 @@ import { useClientDataSWR } from '@/libs/swr'; +import { inboxKeys } from '@/libs/swr/keys'; import { notificationService } from '@/services/notification'; import { serverConfigSelectors, useServerConfigStore } from '@/store/serverConfig'; import { useUserStore } from '@/store/user'; import { authSelectors } from '@/store/user/selectors'; -import { UNREAD_COUNT_KEY } from './InboxDrawer/constants'; - export const INBOX_UNREAD_COUNT_REFRESH_INTERVAL = 10_000; export const useInboxUnreadCount = () => { @@ -14,7 +13,7 @@ export const useInboxUnreadCount = () => { const enabled = enableBusinessFeatures && isLogin === true; const { data: unreadCount = 0 } = useClientDataSWR( - enabled ? UNREAD_COUNT_KEY : null, + enabled ? inboxKeys.unreadCount() : null, () => notificationService.getUnreadCount(), { refreshInterval: INBOX_UNREAD_COUNT_REFRESH_INTERVAL }, ); diff --git a/src/routes/(main)/home/features/InputArea/SkillInstallBanner.tsx b/src/routes/(main)/home/features/InputArea/SkillInstallBanner.tsx index 6162c18f7b8..cb71a9eff7d 100644 --- a/src/routes/(main)/home/features/InputArea/SkillInstallBanner.tsx +++ b/src/routes/(main)/home/features/InputArea/SkillInstallBanner.tsx @@ -1,6 +1,6 @@ 'use client'; -import { getKlavisServerByServerIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; +import { getComposioAppByIdentifier, getLobehubSkillProviderById } from '@lobechat/const'; import { ActionIcon, Flexbox, Icon } from '@lobehub/ui'; import { createStaticStyles } from 'antd-style'; import { Blocks, X } from 'lucide-react'; @@ -70,10 +70,10 @@ const styles = createStaticStyles(({ css, cssVar }) => ({ })); const BANNER_SKILL_IDS = [ - { id: 'gmail', type: 'klavis' }, - { id: 'google-drive', type: 'klavis' }, - { id: 'google-calendar', type: 'klavis' }, - { id: 'slack', type: 'klavis' }, + { id: 'gmail', type: 'composio' }, + { id: 'google-drive', type: 'composio' }, + { id: 'google-calendar', type: 'composio' }, + { id: 'slack', type: 'composio' }, { id: 'notion', type: 'lobehub' }, { id: 'twitter', type: 'lobehub' }, { id: 'github', type: 'lobehub' }, @@ -83,17 +83,17 @@ const SkillInstallBanner = memo(() => { const { t } = useTranslation('plugin'); const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill); - const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis); + const isComposioEnabled = useServerConfigStore(serverConfigSelectors.enableComposio); const updateSystemStatus = useGlobalStore((s) => s.updateSystemStatus); // Prefetch skill connections data so SkillStore opens faster - const [useFetchLobehubSkillConnections, useFetchUserKlavisServers] = useToolStore((s) => [ + const [useFetchLobehubSkillConnections, useFetchUserComposioConnections] = useToolStore((s) => [ s.useFetchLobehubSkillConnections, - s.useFetchUserKlavisServers, + s.useFetchUserComposioConnections, ]); useFetchLobehubSkillConnections(isLobehubSkillEnabled); - useFetchUserKlavisServers(isKlavisEnabled); + useFetchUserComposioConnections(isComposioEnabled); const skillIcons = useMemo(() => { const icons: Array<{ icon: string | React.ComponentType<{ size?: number }>; key: string }> = []; @@ -105,7 +105,7 @@ const SkillInstallBanner = memo(() => { icons.push({ icon: provider.icon, key: provider.id }); } } else { - const server = getKlavisServerByServerIdentifier(skill.id); + const server = getComposioAppByIdentifier(skill.id); if (server) { icons.push({ icon: server.icon, key: server.identifier }); } diff --git a/src/routes/(main)/home/features/InputArea/index.tsx b/src/routes/(main)/home/features/InputArea/index.tsx index bed6721735e..382e3a43a8c 100644 --- a/src/routes/(main)/home/features/InputArea/index.tsx +++ b/src/routes/(main)/home/features/InputArea/index.tsx @@ -41,7 +41,7 @@ const InputArea = () => { ); const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId); const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill); - const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis); + const isComposioEnabled = useServerConfigStore(serverConfigSelectors.enableComposio); const serverConfigInit = useServerConfigStore((s) => s.serverConfigInit); const isSkillBannerDismissed = useGlobalStore( systemStatusSelectors.isBannerDismissed(SKILL_INSTALL_BANNER_ID), @@ -67,7 +67,7 @@ const InputArea = () => { if (!serverConfigInit || !inboxAgentId) return; const candidates: BannerKind[] = []; - if ((isLobehubSkillEnabled || isKlavisEnabled) && !isSkillBannerDismissed) { + if ((isLobehubSkillEnabled || isComposioEnabled) && !isSkillBannerDismissed) { candidates.push('skill'); } if (!isBotIntegrationBannerDismissed) candidates.push('botIntegration'); @@ -79,7 +79,7 @@ const InputArea = () => { }, [ inboxAgentId, isBotIntegrationBannerDismissed, - isKlavisEnabled, + isComposioEnabled, isLobehubSkillEnabled, isMessengerBannerDismissed, isSkillBannerDismissed, diff --git a/src/routes/(main)/memory/features/MemoryAnalysis/useTask.ts b/src/routes/(main)/memory/features/MemoryAnalysis/useTask.ts index a5a0fba3135..bc3592b1501 100644 --- a/src/routes/(main)/memory/features/MemoryAnalysis/useTask.ts +++ b/src/routes/(main)/memory/features/MemoryAnalysis/useTask.ts @@ -2,14 +2,13 @@ import { AsyncTaskStatus } from '@lobechat/types'; import { useEffect } from 'react'; import { useClientDataSWR } from '@/libs/swr'; +import { userMemoryKeys } from '@/libs/swr/keys'; import { type MemoryExtractionTask } from '@/services/userMemory/extraction'; import { memoryExtractionService } from '@/services/userMemory/extraction'; -const SWR_KEY = 'user-memory:analysis-task'; - export const useMemoryAnalysisAsyncTask = (taskId?: string) => { const swr = useClientDataSWR( - taskId ? [SWR_KEY, taskId] : SWR_KEY, + taskId ? userMemoryKeys.analysisTask(taskId) : userMemoryKeys.analysisTask(), () => memoryExtractionService.getTask(taskId), { refreshInterval: (data) => diff --git a/src/routes/(main)/settings/profile/features/KlavisAuthorizationList/index.tsx b/src/routes/(main)/settings/profile/features/ComposioAuthorizationList/index.tsx similarity index 59% rename from src/routes/(main)/settings/profile/features/KlavisAuthorizationList/index.tsx rename to src/routes/(main)/settings/profile/features/ComposioAuthorizationList/index.tsx index 9aa058c5644..ca2aa04d829 100644 --- a/src/routes/(main)/settings/profile/features/KlavisAuthorizationList/index.tsx +++ b/src/routes/(main)/settings/profile/features/ComposioAuthorizationList/index.tsx @@ -1,24 +1,24 @@ -import { KLAVIS_SERVER_TYPES } from '@lobechat/const'; +import { COMPOSIO_APP_TYPES } from '@lobechat/const'; import { Avatar, Flexbox, Tag } from '@lobehub/ui'; import { confirmModal } from '@lobehub/ui/base-ui'; import { memo, useCallback, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useToolStore } from '@/store/tool'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; -interface KlavisAuthItemProps { - server: KlavisServer; +interface ComposioAuthItemProps { + server: ComposioServer; } -const KlavisAuthItem = memo(({ server }) => { +const ComposioAuthItem = memo(({ server }) => { const { t } = useTranslation('auth'); const [isRevoking, setIsRevoking] = useState(false); - const removeKlavisServer = useToolStore((s) => s.removeKlavisServer); + const removeComposioConnection = useToolStore((s) => s.removeComposioConnection); // Get server type configuration (icons, etc.) - const serverType = KLAVIS_SERVER_TYPES.find((item) => item.identifier === server.identifier); + const serverType = COMPOSIO_APP_TYPES.find((item) => item.identifier === server.identifier); // Handle deauthorization const handleRevoke = useCallback(() => { @@ -28,16 +28,16 @@ const KlavisAuthItem = memo(({ server }) => { onOk: async () => { setIsRevoking(true); try { - await removeKlavisServer(server.identifier); + await removeComposioConnection(server.identifier); } finally { setIsRevoking(false); } }, title: t('profile.authorizations.revoke.title', { - name: serverType?.label || server.serverName, + name: serverType?.label || server.label, }), }); - }, [removeKlavisServer, server.identifier, server.serverName, serverType?.label, t]); + }, [removeComposioConnection, server.identifier, server.label, serverType?.label, t]); // Render icon const renderIcon = () => { @@ -55,24 +55,24 @@ const KlavisAuthItem = memo(({ server }) => { {renderIcon()} - {serverType?.label || server.serverName} + {serverType?.label || server.label} ); }); -interface KlavisAuthorizationListProps { - servers: KlavisServer[]; +interface ComposioAuthorizationListProps { + servers: ComposioServer[]; } -export const KlavisAuthorizationList = memo(({ servers }) => { +export const ComposioAuthorizationList = memo(({ servers }) => { return ( {servers.map((server) => ( - + ))} ); }); -export default KlavisAuthorizationList; +export default ComposioAuthorizationList; diff --git a/src/routes/(main)/settings/profile/index.tsx b/src/routes/(main)/settings/profile/index.tsx index ae24db27e6d..49fba2c905a 100644 --- a/src/routes/(main)/settings/profile/index.tsx +++ b/src/routes/(main)/settings/profile/index.tsx @@ -10,15 +10,15 @@ import SettingHeader from '@/routes/(main)/settings/features/SettingHeader'; import { useServerConfigStore } from '@/store/serverConfig'; import { serverConfigSelectors } from '@/store/serverConfig/selectors'; import { useToolStore } from '@/store/tool'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { useUserStore } from '@/store/user'; import { authSelectors, userProfileSelectors } from '@/store/user/selectors'; import AvatarRow from './features/AvatarRow'; +import ComposioAuthorizationList from './features/ComposioAuthorizationList'; import EmailRow from './features/EmailRow'; import FullNameRow from './features/FullNameRow'; import InterestsRow from './features/InterestsRow'; -import KlavisAuthorizationList from './features/KlavisAuthorizationList'; import PasswordRow from './features/PasswordRow'; import ProfileRow from './features/ProfileRow'; import SSOProvidersList from './features/SSOProvidersList'; @@ -41,20 +41,20 @@ const ProfileSetting = () => { ]); const isLoadedAuthProviders = useUserStore(authSelectors.isLoadedAuthProviders); const fetchAuthProviders = useUserStore((s) => s.fetchAuthProviders); - const enableKlavis = useServerConfigStore(serverConfigSelectors.enableKlavis); + const enableComposio = useServerConfigStore(serverConfigSelectors.enableComposio); const disableEmailPassword = useServerConfigStore(serverConfigSelectors.disableEmailPassword); - const [servers, isServersInit, useFetchUserKlavisServers] = useToolStore((s) => [ - s.servers, - s.isServersInit, - s.useFetchUserKlavisServers, + const [servers, isServersInit, useFetchUserComposioConnections] = useToolStore((s) => [ + s.composioServers, + s.isComposioServersInit, + s.useFetchUserComposioConnections, ]); - const connectedServers = servers.filter((s) => s.status === KlavisServerStatus.CONNECTED); + const connectedServers = servers.filter((s) => s.status === ComposioServerStatus.ACTIVE); - // Fetch Klavis servers - useFetchUserKlavisServers(enableKlavis); + // Fetch Composio servers + useFetchUserComposioConnections(enableComposio); const isLoading = - !isUserLoaded || (isLogin && !isLoadedAuthProviders) || (enableKlavis && !isServersInit); + !isUserLoaded || (isLogin && !isLoadedAuthProviders) || (enableComposio && !isServersInit); useEffect(() => { if (isLogin) { @@ -115,11 +115,11 @@ const ProfileSetting = () => { )} - {enableKlavis && connectedServers.length > 0 && ( + {enableComposio && connectedServers.length > 0 && ( <> - + )} diff --git a/src/routes/(main)/settings/provider/detail/default/ClientMode.tsx b/src/routes/(main)/settings/provider/detail/default/ClientMode.tsx index ad4610e5d98..1c1b53fade7 100644 --- a/src/routes/(main)/settings/provider/detail/default/ClientMode.tsx +++ b/src/routes/(main)/settings/provider/detail/default/ClientMode.tsx @@ -5,6 +5,7 @@ import { memo } from 'react'; import Loading from '@/components/Loading/BrandTextLoading'; import { useClientDataSWR } from '@/libs/swr'; +import { providerKeys } from '@/libs/swr/keys'; import { aiProviderService } from '@/services/aiProvider'; import { useAiInfraStore } from '@/store/aiInfra'; @@ -15,7 +16,7 @@ const ClientMode = memo<{ id: string }>(({ id }) => { const useFetchAiProviderItem = useAiInfraStore((s) => s.useFetchAiProviderItem); useFetchAiProviderItem(id); - const { data, isLoading } = useClientDataSWR(`get-client-provider-${id}`, () => + const { data, isLoading } = useClientDataSWR(providerKeys.clientConfig(id), () => aiProviderService.getAiProviderById(id), ); diff --git a/src/routes/(main)/settings/provider/features/ModelList/DisabledModels.tsx b/src/routes/(main)/settings/provider/features/ModelList/DisabledModels.tsx index eb62498a3b3..9716376a798 100644 --- a/src/routes/(main)/settings/provider/features/ModelList/DisabledModels.tsx +++ b/src/routes/(main)/settings/provider/features/ModelList/DisabledModels.tsx @@ -7,6 +7,7 @@ import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import useSWRInfinite from 'swr/infinite'; +import { aiModelKeys } from '@/libs/swr/keys'; import { aiModelService } from '@/services/aiModel'; import { useAiInfraStore } from '@/store/aiInfra'; import { aiModelSelectors } from '@/store/aiInfra/selectors'; @@ -30,7 +31,6 @@ enum SortType { } const PAGE_SIZE = 30; -const FETCH_DISABLED_MODELS_PAGE_KEY = 'FETCH_DISABLED_MODELS_PAGE'; const DisabledModels = memo(({ activeTab, providerId }) => { const { t } = useTranslation(['modelProvider', 'common']); @@ -76,7 +76,7 @@ const DisabledModels = memo(({ activeTab, providerId }) => // start fetching after the initial list from store const offset = disabledModels.length + pageIndex * PAGE_SIZE; - return [FETCH_DISABLED_MODELS_PAGE_KEY, providerId, offset] as const; + return aiModelKeys.disabledModelsPage(providerId, offset); }, [disabledModels.length, providerId, remoteEnabled], ); diff --git a/src/routes/(main)/settings/provider/features/ProviderConfig/OAuthDeviceFlowAuth/index.tsx b/src/routes/(main)/settings/provider/features/ProviderConfig/OAuthDeviceFlowAuth/index.tsx index 562015e67cc..b32b93b942f 100644 --- a/src/routes/(main)/settings/provider/features/ProviderConfig/OAuthDeviceFlowAuth/index.tsx +++ b/src/routes/(main)/settings/provider/features/ProviderConfig/OAuthDeviceFlowAuth/index.tsx @@ -142,7 +142,7 @@ const OAuthDeviceFlowAuth = memo( { providerId }, { refetchOnWindowFocus: true }, ); - const isAuthenticated = authStatus?.isAuthenticated ?? false; + const isAuthenticated = authStatus?.status === 'ACTIVE'; const username = authStatus?.username; const avatarUrl = authStatus?.avatarUrl; diff --git a/src/routes/(main)/settings/provider/features/ProviderConfig/index.tsx b/src/routes/(main)/settings/provider/features/ProviderConfig/index.tsx index a7f012a051f..87482d0e61d 100644 --- a/src/routes/(main)/settings/provider/features/ProviderConfig/index.tsx +++ b/src/routes/(main)/settings/provider/features/ProviderConfig/index.tsx @@ -156,7 +156,7 @@ const ProviderConfig = memo( { providerId: id }, { enabled: isOAuthProvider, refetchOnWindowFocus: true }, ); - const isOAuthAuthenticated = oauthStatus?.isAuthenticated ?? false; + const isOAuthAuthenticated = oauthStatus?.status === 'ACTIVE'; const [ data, diff --git a/src/routes/(main)/settings/skill/features/KlavisSkillItem.tsx b/src/routes/(main)/settings/skill/features/ComposioSkillItem.tsx similarity index 59% rename from src/routes/(main)/settings/skill/features/KlavisSkillItem.tsx rename to src/routes/(main)/settings/skill/features/ComposioSkillItem.tsx index c5897147c23..6c1212edd7e 100644 --- a/src/routes/(main)/settings/skill/features/KlavisSkillItem.tsx +++ b/src/routes/(main)/settings/skill/features/ComposioSkillItem.tsx @@ -1,37 +1,41 @@ 'use client'; -import { type KlavisServerType } from '@lobechat/const'; +import { type ComposioAppType } from '@lobechat/const'; import { Avatar, Button as LobeButton, DropdownMenu, Flexbox, Icon, Tooltip } from '@lobehub/ui'; import { confirmModal } from '@lobehub/ui/base-ui'; import { Button } from 'antd'; import { cssVar } from 'antd-style'; -import { Loader2, MoreHorizontalIcon, SquareArrowOutUpRight, Unplug } from 'lucide-react'; +import { + Loader2, + MoreHorizontalIcon, + RotateCcw, + SquareArrowOutUpRight, + Trash2, + Unplug, +} from 'lucide-react'; import { memo, useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; -import { createKlavisSkillDetailModal } from '@/features/SkillStore/SkillDetail'; import { usePermission } from '@/hooks/usePermission'; import { useToolStore } from '@/store/tool'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; -import { useUserStore } from '@/store/user'; -import { userProfileSelectors } from '@/store/user/selectors'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { styles } from './style'; const POLL_INTERVAL_MS = 1000; const POLL_TIMEOUT_MS = 15_000; -interface KlavisSkillItemProps { +interface ComposioSkillItemProps { isSelected?: boolean; onDelete?: () => void; onSelect?: () => void; - server?: KlavisServer; - serverType: KlavisServerType; + server?: ComposioServer; + serverType: ComposioAppType; } -const KlavisSkillItem = memo( - ({ serverType, server, isSelected, onSelect, onDelete }) => { +const ComposioSkillItem = memo( + ({ serverType, server, isSelected, onSelect }) => { const { t } = useTranslation('setting'); const { allowed: canCreate, reason: createReason } = usePermission('create_content'); const { allowed: canEdit, reason: editReason } = usePermission('edit_own_content'); @@ -43,10 +47,10 @@ const KlavisSkillItem = memo( const pollIntervalRef = useRef | null>(null); const pollTimeoutRef = useRef | null>(null); - const userId = useUserStore(userProfileSelectors.userId); - const createKlavisServer = useToolStore((s) => s.createKlavisServer); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); - const removeKlavisServer = useToolStore((s) => s.removeKlavisServer); + const createComposioConnection = useToolStore((s) => s.createComposioConnection); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); + const removeComposioConnection = useToolStore((s) => s.removeComposioConnection); + const reauthorizeComposioConnection = useToolStore((s) => s.reauthorizeComposioConnection); const cleanup = useCallback(() => { if (windowCheckIntervalRef.current) { @@ -72,20 +76,20 @@ const KlavisSkillItem = memo( }, [cleanup]); useEffect(() => { - if (server?.status === KlavisServerStatus.CONNECTED && isWaitingAuth) { + if (server?.status === ComposioServerStatus.ACTIVE && isWaitingAuth) { cleanup(); } }, [server?.status, isWaitingAuth, cleanup]); const startFallbackPolling = useCallback( - (serverName: string) => { + (identifier: string) => { if (pollIntervalRef.current) return; pollIntervalRef.current = setInterval(async () => { try { - await refreshKlavisServerTools(serverName); + await refreshComposioConnectionStatus(identifier); } catch (error) { - console.info('[Klavis] Polling check (expected during auth):', error); + console.info('[Composio] Polling check (expected during auth):', error); } }, POLL_INTERVAL_MS); @@ -97,11 +101,11 @@ const KlavisSkillItem = memo( setIsWaitingAuth(false); }, POLL_TIMEOUT_MS); }, - [refreshKlavisServerTools], + [refreshComposioConnectionStatus], ); const startWindowMonitor = useCallback( - (oauthWindow: Window, serverName: string) => { + (oauthWindow: Window, identifier: string) => { windowCheckIntervalRef.current = setInterval(async () => { try { if (oauthWindow.closed) { @@ -110,33 +114,32 @@ const KlavisSkillItem = memo( windowCheckIntervalRef.current = null; } oauthWindowRef.current = null; - // Start polling after window closes - startFallbackPolling(serverName); + startFallbackPolling(identifier); } } catch { - console.info('[Klavis] COOP blocked window.closed access, falling back to polling'); + console.info('[Composio] COOP blocked window.closed access, falling back to polling'); if (windowCheckIntervalRef.current) { clearInterval(windowCheckIntervalRef.current); windowCheckIntervalRef.current = null; } - startFallbackPolling(serverName); + startFallbackPolling(identifier); } }, 500); }, - [refreshKlavisServerTools, startFallbackPolling], + [startFallbackPolling], ); const openOAuthWindow = useCallback( - (oauthUrl: string, serverName: string) => { + (redirectUrl: string, identifier: string) => { cleanup(); setIsWaitingAuth(true); - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; - startWindowMonitor(oauthWindow, serverName); + startWindowMonitor(oauthWindow, identifier); } else { - startFallbackPolling(serverName); + startFallbackPolling(identifier); } }, [cleanup, startWindowMonitor, startFallbackPolling], @@ -144,31 +147,50 @@ const KlavisSkillItem = memo( const handleConnect = async () => { if (!canCreate || !canEdit) return; - if (!userId) return; if (server) return; setIsConnecting(true); try { - const newServer = await createKlavisServer({ + const newServer = await createComposioConnection({ + appSlug: serverType.appSlug, identifier: serverType.identifier, - serverName: serverType.serverName, - userId, + label: serverType.label, }); if (newServer) { - if (newServer.isAuthenticated) { - await refreshKlavisServerTools(newServer.identifier); - } else if (newServer.oauthUrl) { - openOAuthWindow(newServer.oauthUrl, newServer.identifier); + if (newServer.status === ComposioServerStatus.ACTIVE) { + await refreshComposioConnectionStatus(newServer.identifier); + } else if (newServer.redirectUrl) { + openOAuthWindow(newServer.redirectUrl, newServer.identifier); } } } catch (error) { - console.error('[Klavis] Failed to connect server:', error); + console.error('[Composio] Failed to connect server:', error); } finally { setIsConnecting(false); } }; + const handleReauthorize = async () => { + if (!canCreate || !canEdit || !server) return; + setIsConnecting(true); + try { + const newServer = await reauthorizeComposioConnection(server.identifier); + if (newServer?.redirectUrl) { + openOAuthWindow(newServer.redirectUrl, newServer.identifier); + } + } catch (error) { + console.error('[Composio] Failed to re-authorize server:', error); + } finally { + setIsConnecting(false); + } + }; + + const handleDelete = async () => { + if (!canEdit || !server) return; + await removeComposioConnection(server.identifier); + }; + const handleDisconnect = () => { if (!canEdit) return; if (!server) return; @@ -178,7 +200,7 @@ const KlavisSkillItem = memo( okButtonProps: { danger: true }, okText: t('tools.lobehubSkill.disconnect'), onOk: async () => { - await removeKlavisServer(server.identifier); + await removeComposioConnection(server.identifier); }, title: t('tools.lobehubSkill.disconnectConfirm.title', { name: serverType.label }), }); @@ -196,25 +218,25 @@ const KlavisSkillItem = memo( if (!server) { return ( - {t('tools.klavis.disconnected', { defaultValue: 'Disconnected' })} + {t('tools.composio.disconnected', { defaultValue: 'Disconnected' })} ); } switch (server.status) { - case KlavisServerStatus.CONNECTED: { - return {t('tools.klavis.connected')}; + case ComposioServerStatus.ACTIVE: { + return {t('tools.composio.connected')}; } - case KlavisServerStatus.PENDING_AUTH: { - return {t('tools.klavis.authRequired')}; + case ComposioServerStatus.PENDING_AUTH: { + return {t('tools.composio.authRequired')}; } - case KlavisServerStatus.ERROR: { - return {t('tools.klavis.error')}; + case ComposioServerStatus.ERROR: { + return {t('tools.composio.error')}; } default: { return ( - {t('tools.klavis.disconnected', { defaultValue: 'Disconnected' })} + {t('tools.composio.disconnected', { defaultValue: 'Disconnected' })} ); } @@ -225,7 +247,7 @@ const KlavisSkillItem = memo( if (isConnecting || isWaitingAuth) { return ( ); } @@ -239,31 +261,48 @@ const KlavisSkillItem = memo( type="default" onClick={handleConnect} > - {t('tools.klavis.connect', { defaultValue: 'Connect' })} + {t('tools.composio.connect', { defaultValue: 'Connect' })} ); } - if (server.status === KlavisServerStatus.PENDING_AUTH) { + // A pending/errored connection often means the OAuth link expired. Offer + // both re-authorize (clean up the stale connection + mint a fresh link) + // and delete, so the row can never get stuck unable to retry or be removed. + if ( + server.status === ComposioServerStatus.PENDING_AUTH || + server.status === ComposioServerStatus.ERROR + ) { return ( - + + + + ); } - if (server.status === KlavisServerStatus.CONNECTED) { + if (server.status === ComposioServerStatus.ACTIVE) { return ( ( disabled: !canEdit, icon: , key: 'disconnect', - label: t('tools.klavis.disconnect', { defaultValue: 'Disconnect' }), + label: t('tools.composio.disconnect', { defaultValue: 'Disconnect' }), onClick: handleDisconnect, }, ]} @@ -288,7 +327,7 @@ const KlavisSkillItem = memo( return null; }; - const isConnected = server?.status === KlavisServerStatus.CONNECTED; + const isConnected = server?.status === ComposioServerStatus.ACTIVE; return ( ( align="center" gap={8} style={{ cursor: onSelect ? undefined : 'pointer' }} - onClick={ - onSelect - ? undefined - : () => - createKlavisSkillDetailModal({ - identifier: serverType.identifier, - serverName: serverType.serverName, - }) - } >
{renderIcon()} @@ -339,6 +369,6 @@ const KlavisSkillItem = memo( }, ); -KlavisSkillItem.displayName = 'KlavisSkillItem'; +ComposioSkillItem.displayName = 'ComposioSkillItem'; -export default KlavisSkillItem; +export default ComposioSkillItem; diff --git a/src/routes/(main)/settings/skill/features/SkillList.tsx b/src/routes/(main)/settings/skill/features/SkillList.tsx index 0137700b418..5abce3fdd5a 100644 --- a/src/routes/(main)/settings/skill/features/SkillList.tsx +++ b/src/routes/(main)/settings/skill/features/SkillList.tsx @@ -1,10 +1,10 @@ 'use client'; import { - getKlavisServerByServerIdentifier, + COMPOSIO_APP_TYPES, + type ComposioAppType, + getComposioAppByIdentifier, getLobehubSkillProviderById, - KLAVIS_SERVER_TYPES, - type KlavisServerType, LOBEHUB_SKILL_PROVIDERS, type LobehubSkillProviderType, RECOMMENDED_SKILLS, @@ -26,18 +26,18 @@ import { useToolStore } from '@/store/tool'; import { agentSkillsSelectors, builtinToolSelectors, - klavisStoreSelectors, + composioStoreSelectors, lobehubSkillStoreSelectors, pluginSelectors, } from '@/store/tool/selectors'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; import { connectorSelectors } from '@/store/tool/slices/connector'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; import { LobehubSkillStatus } from '@/store/tool/slices/lobehubSkillStore/types'; import { type LobeToolType } from '@/types/tool/tool'; import AgentSkillItem from './AgentSkillItem'; import BuiltinSkillItem from './BuiltinSkillItem'; -import KlavisSkillItem from './KlavisSkillItem'; +import ComposioSkillItem from './ComposioSkillItem'; import LobehubSkillItem from './LobehubSkillItem'; import McpSkillItem from './McpSkillItem'; import type { ToolDetailType } from './SkillDetail'; @@ -93,9 +93,9 @@ const SkillList = memo( const [collapsed, setCollapsed] = useState>(new Set()); const isLobehubSkillEnabled = useServerConfigStore(serverConfigSelectors.enableLobehubSkill); - const isKlavisEnabled = useServerConfigStore(serverConfigSelectors.enableKlavis); + const isComposioEnabled = useServerConfigStore(serverConfigSelectors.enableComposio); const allLobehubSkillServers = useToolStore(lobehubSkillStoreSelectors.getServers, isEqual); - const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); + const allComposioServers = useToolStore(composioStoreSelectors.getServers, isEqual); const installedPluginList = useToolStore(pluginSelectors.installedPluginMetaList, isEqual); const marketAgentSkills = useToolStore(agentSkillsSelectors.getMarketAgentSkills, isEqual); const userAgentSkills = useToolStore(agentSkillsSelectors.getUserAgentSkills, isEqual); @@ -111,19 +111,19 @@ const SkillList = memo( const [ useFetchLobehubSkillConnections, - useFetchUserKlavisServers, + useFetchUserComposioConnections, useFetchAgentSkills, useFetchUninstalledBuiltinTools, ] = useToolStore((s) => [ s.useFetchLobehubSkillConnections, - s.useFetchUserKlavisServers, + s.useFetchUserComposioConnections, s.useFetchAgentSkills, s.useFetchUninstalledBuiltinTools, ]); useFetchInstalledPlugins(); useFetchLobehubSkillConnections(isLobehubSkillEnabled); - useFetchUserKlavisServers(isKlavisEnabled); + useFetchUserComposioConnections(isComposioEnabled); useFetchAgentSkills(true); useFetchUninstalledBuiltinTools(true); @@ -137,8 +137,8 @@ const SkillList = memo( return allLobehubSkillServers.find((server) => server.identifier === providerId); }; - const getKlavisServerByIdentifier = (identifier: string) => { - return allKlavisServers.find((server) => server.identifier === identifier); + const getComposioServerByIdentifier = (identifier: string) => { + return allComposioServers.find((server) => server.identifier === identifier); }; const getBuiltinToolByIdentifier = (identifier: string) => { @@ -150,7 +150,7 @@ const SkillList = memo( }; // Separate skills into three categories: - // 1. Integrations (Builtin, LobeHub and Klavis skills) + // 1. Integrations (Builtin, LobeHub and Composio skills) // 2. Community MCP Tools (type === 'plugin') // 3. Custom MCP Tools (type === 'customPlugin') const { integrations, communityMCPs, customMCPs } = useMemo(() => { @@ -158,7 +158,7 @@ const SkillList = memo( | { builtinAgentSkill: BuiltinSkill; type: 'builtinAgent' } | { builtinTool: LobeBuiltinTool; type: 'builtin' } | { provider: LobehubSkillProviderType; type: 'lobehub' } - | { serverType: KlavisServerType; type: 'klavis' }; + | { serverType: ComposioAppType; type: 'composio' }; let integrationItems: IntegrationItem[] = []; @@ -169,7 +169,7 @@ const SkillList = memo( const addedBuiltinIds = new Set(); const addedLobehubIds = new Set(); - const addedKlavisIds = new Set(); + const addedComposioIds = new Set(); // If RECOMMENDED_SKILLS is configured, use it to build the list if (RECOMMENDED_SKILLS.length > 0) { @@ -186,11 +186,11 @@ const SkillList = memo( integrationItems.push({ provider, type: 'lobehub' }); addedLobehubIds.add(skill.id); } - } else if (skill.type === RecommendedSkillType.Klavis && isKlavisEnabled) { - const serverType = getKlavisServerByServerIdentifier(skill.id); + } else if (skill.type === RecommendedSkillType.Composio && isComposioEnabled) { + const serverType = getComposioAppByIdentifier(skill.id); if (serverType) { - integrationItems.push({ serverType, type: 'klavis' }); - addedKlavisIds.add(skill.id); + integrationItems.push({ serverType, type: 'composio' }); + addedComposioIds.add(skill.id); } } } @@ -221,16 +221,16 @@ const SkillList = memo( } } - // Also add connected Klavis skills that are not in RECOMMENDED_SKILLS - if (isKlavisEnabled) { - for (const server of allKlavisServers) { + // Also add connected Composio skills that are not in RECOMMENDED_SKILLS + if (isComposioEnabled) { + for (const server of allComposioServers) { if ( - server.status === KlavisServerStatus.CONNECTED && - !addedKlavisIds.has(server.identifier) + server.status === ComposioServerStatus.ACTIVE && + !addedComposioIds.has(server.identifier) ) { - const serverType = getKlavisServerByServerIdentifier(server.identifier); + const serverType = getComposioAppByIdentifier(server.identifier); if (serverType) { - integrationItems.push({ serverType, type: 'klavis' }); + integrationItems.push({ serverType, type: 'composio' }); } } } @@ -250,21 +250,21 @@ const SkillList = memo( } } - // Add klavis skills - if (isKlavisEnabled) { - for (const serverType of KLAVIS_SERVER_TYPES) { - integrationItems.push({ serverType, type: 'klavis' }); + // Add composio skills + if (isComposioEnabled) { + for (const serverType of COMPOSIO_APP_TYPES) { + integrationItems.push({ serverType, type: 'composio' }); } } - // Filter integrations: show all builtin and lobehub skills, but only connected klavis + // Filter integrations: show all builtin and lobehub skills, but only connected composio integrationItems = integrationItems.filter((item) => { if (item.type === 'builtinAgent' || item.type === 'builtin' || item.type === 'lobehub') { return true; } return ( - getKlavisServerByIdentifier(item.serverType.identifier)?.status === - KlavisServerStatus.CONNECTED + getComposioServerByIdentifier(item.serverType.identifier)?.status === + ComposioServerStatus.ACTIVE ); }); } @@ -284,10 +284,10 @@ const SkillList = memo( LobehubSkillStatus.CONNECTED ); } - case 'klavis': { + case 'composio': { return ( - getKlavisServerByIdentifier(item.serverType.identifier)?.status === - KlavisServerStatus.CONNECTED + getComposioServerByIdentifier(item.serverType.identifier)?.status === + ComposioServerStatus.ACTIVE ); } } @@ -313,9 +313,9 @@ const SkillList = memo( }, [ installedPluginList, isLobehubSkillEnabled, - isKlavisEnabled, + isComposioEnabled, allLobehubSkillServers, - allKlavisServers, + allComposioServers, allBuiltinTools, uninstalledBuiltinTools, builtinSkills, @@ -405,7 +405,7 @@ const SkillList = memo( const builtinToolItems = integrations.filter((i) => i.type === 'builtin'); const builtinSkillItems = integrations.filter((i) => i.type === 'builtinAgent'); const communitySkillItems = integrations.filter( - (i) => i.type === 'lobehub' || i.type === 'klavis', + (i) => i.type === 'lobehub' || i.type === 'composio', ); const toggleSection = (key: string) => { @@ -436,7 +436,7 @@ const SkillList = memo( // Skills tab: prompt/agent-based skills (show description/content) const hasBuiltinTools = builtinToolItems.length > 0 && isConnectorView; const hasBuiltinSkills = builtinSkillItems.length > 0 && !isConnectorView; - // Skills tab only shows agent-based community skills; Lobehub/Klavis OAuth + // Skills tab only shows agent-based community skills; Lobehub/Composio OAuth // connectors live exclusively in the Connectors view (hasCommunityConnectors). const hasCommunitySkills = !isConnectorView && marketAgentSkills.length > 0; const hasCommunityTools = communityMCPs.length > 0 && isConnectorView; @@ -445,7 +445,7 @@ const SkillList = memo( const hasCustomConnectors = isConnectorView && (customMCPs.length > 0 || customConnectors.length > 0); const hasCustomSkills = userAgentSkills.length > 0 && !isConnectorView; - // Lobehub/Klavis OAuth skills go in Connectors tab (they provide tools) + // Lobehub/Composio OAuth skills go in Connectors tab (they provide tools) const hasCommunityConnectors = communitySkillItems.length > 0 && isConnectorView; return ( @@ -495,7 +495,7 @@ const SkillList = memo( }), )} - {/* Connector view: Lobehub/Klavis OAuth connectors */} + {/* Connector view: Lobehub/Composio OAuth connectors */} {hasCommunityConnectors && renderSection( 'communityConnectors', @@ -516,10 +516,10 @@ const SkillList = memo( ); } return ( - (({ inShare }) => { const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR('stats-sessions', async () => ({ + const { data, isLoading } = useClientDataSWR(statsKeys.sessions(), async () => ({ count: await sessionService.countSessions(), prevCount: await sessionService.countSessions({ endDate: lastMonth().format('YYYY-MM-DD') }), })); diff --git a/src/routes/(main)/settings/stats/features/overview/TotalMessages.tsx b/src/routes/(main)/settings/stats/features/overview/TotalMessages.tsx index 274168efc88..40197ac364d 100644 --- a/src/routes/(main)/settings/stats/features/overview/TotalMessages.tsx +++ b/src/routes/(main)/settings/stats/features/overview/TotalMessages.tsx @@ -5,6 +5,7 @@ import Statistic from '@/components/Statistic'; import StatisticCard from '@/components/StatisticCard'; import TitleWithPercentage from '@/components/StatisticCard/TitleWithPercentage'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import { formatIntergerNumber } from '@/utils/format'; import { lastMonth } from '@/utils/time'; @@ -13,7 +14,7 @@ import TotalCard from './ShareButton/TotalCard'; const TotalMessages = memo<{ inShare?: boolean; mobile?: boolean }>(({ inShare }) => { const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR('stats-messages', async () => ({ + const { data, isLoading } = useClientDataSWR(statsKeys.messages(), async () => ({ count: await messageService.countMessages(), prevCount: await messageService.countMessages({ endDate: lastMonth().format('YYYY-MM-DD') }), })); diff --git a/src/routes/(main)/settings/stats/features/overview/TotalTokens.tsx b/src/routes/(main)/settings/stats/features/overview/TotalTokens.tsx index 8cee02e2dad..b65d47aa231 100644 --- a/src/routes/(main)/settings/stats/features/overview/TotalTokens.tsx +++ b/src/routes/(main)/settings/stats/features/overview/TotalTokens.tsx @@ -6,6 +6,7 @@ import Statistic from '@/components/Statistic'; import StatisticCard from '@/components/StatisticCard'; import TitleWithPercentage from '@/components/StatisticCard/TitleWithPercentage'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import { formatShortenNumber } from '@/utils/format'; import { lastMonth } from '@/utils/time'; @@ -22,9 +23,8 @@ import TotalCard from './ShareButton/TotalCard'; const TotalTokens = memo<{ inShare?: boolean }>(({ inShare }) => { const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR( - ['stats-heatmaps', HeatmapType.Tokens].join('-'), - () => messageService.getTokenHeatmaps(), + const { data, isLoading } = useClientDataSWR(statsKeys.heatmaps(HeatmapType.Tokens), () => + messageService.getTokenHeatmaps(), ); const { count, prevCount } = useMemo(() => { diff --git a/src/routes/(main)/settings/stats/features/overview/TotalTopics.tsx b/src/routes/(main)/settings/stats/features/overview/TotalTopics.tsx index 600040ca4ea..d0967df2013 100644 --- a/src/routes/(main)/settings/stats/features/overview/TotalTopics.tsx +++ b/src/routes/(main)/settings/stats/features/overview/TotalTopics.tsx @@ -5,6 +5,7 @@ import Statistic from '@/components/Statistic'; import StatisticCard from '@/components/StatisticCard'; import TitleWithPercentage from '@/components/StatisticCard/TitleWithPercentage'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { topicService } from '@/services/topic'; import { formatIntergerNumber } from '@/utils/format'; import { lastMonth } from '@/utils/time'; @@ -13,7 +14,7 @@ import TotalCard from './ShareButton/TotalCard'; const TotalMessages = memo<{ inShare?: boolean; mobile?: boolean }>(({ inShare }) => { const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR('stats-topics', async () => ({ + const { data, isLoading } = useClientDataSWR(statsKeys.topics(), async () => ({ count: await topicService.countTopics(), prevCount: await topicService.countTopics({ endDate: lastMonth().format('YYYY-MM-DD') }), })); diff --git a/src/routes/(main)/settings/stats/features/overview/Welcome.tsx b/src/routes/(main)/settings/stats/features/overview/Welcome.tsx index 73cdc7db520..be0c84ca9ac 100644 --- a/src/routes/(main)/settings/stats/features/overview/Welcome.tsx +++ b/src/routes/(main)/settings/stats/features/overview/Welcome.tsx @@ -5,6 +5,7 @@ import { memo } from 'react'; import { Trans, useTranslation } from 'react-i18next'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { userService } from '@/services/user'; import { useUserStore } from '@/store/user'; import { userProfileSelectors } from '@/store/user/selectors'; @@ -26,7 +27,7 @@ const Welcome = memo<{ mobile?: boolean }>(({ mobile }) => { userProfileSelectors.username(s), ]); - const { data, isLoading } = useClientDataSWR('welcome', async () => + const { data, isLoading } = useClientDataSWR(statsKeys.welcome(), async () => userService.getUserRegistrationDuration(), ); diff --git a/src/routes/(main)/settings/stats/features/rankings/AssistantsRank.tsx b/src/routes/(main)/settings/stats/features/rankings/AssistantsRank.tsx index e6891bc90f5..bedc39f3ee4 100644 --- a/src/routes/(main)/settings/stats/features/rankings/AssistantsRank.tsx +++ b/src/routes/(main)/settings/stats/features/rankings/AssistantsRank.tsx @@ -10,6 +10,7 @@ import { SESSION_CHAT_URL } from '@/const/url'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; import Link from '@/libs/router/Link'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { agentService } from '@/services/agent'; import { useAgentStore } from '@/store/agent'; import { builtinAgentSelectors } from '@/store/agent/selectors'; @@ -22,7 +23,7 @@ export const AssistantsRank = memo<{ mobile?: boolean }>(({ mobile }) => { const { t } = useTranslation(['auth', 'chat']); const navigate = useWorkspaceAwareNavigate(); const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId); - const { data, isLoading } = useClientDataSWR('rank-agents', async () => + const { data, isLoading } = useClientDataSWR(statsKeys.rankAgents(), async () => agentService.rankAgents(), ); diff --git a/src/routes/(main)/settings/stats/features/rankings/ModelsRank.tsx b/src/routes/(main)/settings/stats/features/rankings/ModelsRank.tsx index 35593e7240d..d5418030ab0 100644 --- a/src/routes/(main)/settings/stats/features/rankings/ModelsRank.tsx +++ b/src/routes/(main)/settings/stats/features/rankings/ModelsRank.tsx @@ -7,6 +7,7 @@ import { memo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import StatsFormGroup from '../components/StatsFormGroup'; @@ -14,7 +15,7 @@ import StatsFormGroup from '../components/StatsFormGroup'; export const TopicsRank = memo(() => { const [open, setOpen] = useState(false); const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR('rank-models', async () => + const { data, isLoading } = useClientDataSWR(statsKeys.rankModels(), async () => messageService.rankModels(), ); diff --git a/src/routes/(main)/settings/stats/features/rankings/TopicsRank.tsx b/src/routes/(main)/settings/stats/features/rankings/TopicsRank.tsx index 2a08960ceea..9345bddc1e8 100644 --- a/src/routes/(main)/settings/stats/features/rankings/TopicsRank.tsx +++ b/src/routes/(main)/settings/stats/features/rankings/TopicsRank.tsx @@ -10,6 +10,7 @@ import { SESSION_CHAT_TOPIC_URL } from '@/const/url'; import { useWorkspaceAwareNavigate } from '@/features/Workspace/useWorkspaceAwareNavigate'; import Link from '@/libs/router/Link'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { topicService } from '@/services/topic'; import { useAgentStore } from '@/store/agent'; import { builtinAgentSelectors } from '@/store/agent/selectors'; @@ -22,7 +23,7 @@ export const TopicsRank = memo<{ mobile?: boolean }>(({ mobile }) => { const { t } = useTranslation('auth'); const navigate = useWorkspaceAwareNavigate(); const inboxAgentId = useAgentStore(builtinAgentSelectors.inboxAgentId); - const { data, isLoading } = useClientDataSWR('rank-topics', async () => + const { data, isLoading } = useClientDataSWR(statsKeys.rankTopics(), async () => topicService.rankTopics(), ); diff --git a/src/routes/(main)/settings/stats/features/usage/UsageTable.tsx b/src/routes/(main)/settings/stats/features/usage/UsageTable.tsx index 503368b4bb5..50be54210ad 100644 --- a/src/routes/(main)/settings/stats/features/usage/UsageTable.tsx +++ b/src/routes/(main)/settings/stats/features/usage/UsageTable.tsx @@ -8,6 +8,7 @@ import { useTranslation } from 'react-i18next'; import InlineTable from '@/components/InlineTable'; import { parseAsInteger, useQueryParam } from '@/hooks/useQueryParam'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { usageService } from '@/services/usage'; import { formatDate, formatNumber } from '@/utils/format'; @@ -16,7 +17,7 @@ import { type UsageChartProps } from '../../types'; const UsageTable = memo(({ dateStrings }) => { const { t } = useTranslation('auth'); - const { data, isLoading, mutate } = useClientDataSWR('usage-logs', async () => + const { data, isLoading, mutate } = useClientDataSWR(statsKeys.usageLogs(), async () => usageService.findByMonth(dateStrings), ); diff --git a/src/routes/(main)/settings/stats/features/visualization/AiHeatmaps.tsx b/src/routes/(main)/settings/stats/features/visualization/AiHeatmaps.tsx index aca35880c8d..5f18fd188e6 100644 --- a/src/routes/(main)/settings/stats/features/visualization/AiHeatmaps.tsx +++ b/src/routes/(main)/settings/stats/features/visualization/AiHeatmaps.tsx @@ -7,6 +7,7 @@ import { memo, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import { formatIntergerNumber, formatShortenNumber } from '@/utils/format'; @@ -23,7 +24,7 @@ const AiHeatmaps = memo< ); const isTokens = type === HeatmapType.Tokens; - const { data, isLoading } = useClientDataSWR(['stats-heatmaps', type].join('-'), async () => + const { data, isLoading } = useClientDataSWR(statsKeys.heatmaps(type), async () => isTokens ? messageService.getTokenHeatmaps() : messageService.getHeatmaps(), ); diff --git a/src/routes/(main)/settings/stats/features/visualization/HeatmapStats.tsx b/src/routes/(main)/settings/stats/features/visualization/HeatmapStats.tsx index fbc23f725ef..9fc107d56b5 100644 --- a/src/routes/(main)/settings/stats/features/visualization/HeatmapStats.tsx +++ b/src/routes/(main)/settings/stats/features/visualization/HeatmapStats.tsx @@ -5,6 +5,7 @@ import { Fragment, memo, useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import { messageService } from '@/services/message'; import { topicService } from '@/services/topic'; import { formatShortenNumber } from '@/utils/format'; @@ -35,13 +36,12 @@ const formatDuration = (seconds?: number) => { const HeatmapStats = memo(() => { const { t } = useTranslation('auth'); - const { data, isLoading } = useClientDataSWR( - ['stats-heatmaps', HeatmapType.Tokens].join('-'), - () => messageService.getTokenHeatmaps(), + const { data, isLoading } = useClientDataSWR(statsKeys.heatmaps(HeatmapType.Tokens), () => + messageService.getTokenHeatmaps(), ); const loading = isLoading || !data; - const { data: maxTaskDuration } = useClientDataSWR('stats-max-task-duration', () => + const { data: maxTaskDuration } = useClientDataSWR(statsKeys.maxTaskDuration(), () => topicService.getMaxTaskDuration(), ); diff --git a/src/routes/(main)/settings/stats/index.tsx b/src/routes/(main)/settings/stats/index.tsx index de814078508..ddf4a6f9542 100644 --- a/src/routes/(main)/settings/stats/index.tsx +++ b/src/routes/(main)/settings/stats/index.tsx @@ -10,6 +10,7 @@ import { memo, type ReactNode, useEffect, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { useClientDataSWR } from '@/libs/swr'; +import { statsKeys } from '@/libs/swr/keys'; import SettingHeader from '@/routes/(main)/settings/features/SettingHeader'; import { usageService } from '@/services/usage'; @@ -54,7 +55,7 @@ const StatsSetting = memo( const [dateRange, setDateRange] = useState(dayjs(new Date())); const [dateStrings, setDateStrings] = useState(); - const { data, isLoading, mutate } = useClientDataSWR('usage-stat', async () => + const { data, isLoading, mutate } = useClientDataSWR(statsKeys.usageStat(), async () => usageService.findAndGroupByDay(dateStrings), ); diff --git a/src/routes/(mobile)/(home)/features/SessionListContent/List/AddButton.tsx b/src/routes/(mobile)/(home)/features/SessionListContent/List/AddButton.tsx index c6e47b3b1c6..58a981bcc4e 100644 --- a/src/routes/(mobile)/(home)/features/SessionListContent/List/AddButton.tsx +++ b/src/routes/(mobile)/(home)/features/SessionListContent/List/AddButton.tsx @@ -4,6 +4,7 @@ import { memo } from 'react'; import { useTranslation } from 'react-i18next'; import { useActionSWR } from '@/libs/swr'; +import { sessionKeys } from '@/libs/swr/keys'; import { useServerConfigStore } from '@/store/serverConfig'; import { useSessionStore } from '@/store/session'; @@ -11,7 +12,7 @@ const AddButton = memo<{ groupId?: string }>(({ groupId }) => { const { t } = useTranslation('chat'); const createSession = useSessionStore((s) => s.createSession); const mobile = useServerConfigStore((s) => s.isMobile); - const { mutate, isValidating } = useActionSWR(['session.createSession', groupId], () => { + const { mutate, isValidating } = useActionSWR(sessionKeys.createSession(groupId), () => { return createSession({ group: groupId }); }); diff --git a/src/routes/onboarding/components/KlavisServerList/components/KlavisServerItem.tsx b/src/routes/onboarding/components/ComposioServerList/components/ComposioServerItem.tsx similarity index 54% rename from src/routes/onboarding/components/KlavisServerList/components/KlavisServerItem.tsx rename to src/routes/onboarding/components/ComposioServerList/components/ComposioServerItem.tsx index 9ed4518be52..2390aeb73eb 100644 --- a/src/routes/onboarding/components/KlavisServerList/components/KlavisServerItem.tsx +++ b/src/routes/onboarding/components/ComposioServerList/components/ComposioServerItem.tsx @@ -4,38 +4,40 @@ import { Block, Flexbox, Text } from '@lobehub/ui'; import { cssVar } from 'antd-style'; import { memo } from 'react'; -import { type KlavisServerType } from '@/const/index'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { type ComposioAppType } from '@/const/index'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; -import { useKlavisOAuth } from '../hooks/useKlavisOAuth'; -import { useKlavisServerActions } from '../hooks/useKlavisServerActions'; +import { useComposioOAuth } from '../hooks/useComposioOAuth'; +import { useComposioServerActions } from '../hooks/useComposioServerActions'; import ServerIcon from './ServerIcon'; import ServerStatusControl from './ServerStatusControl'; -interface KlavisServerItemProps { - icon: KlavisServerType['icon']; +interface ComposioServerItemProps { + appSlug: string; + icon: ComposioAppType['icon']; identifier: string; label: string; - server?: KlavisServer; - serverName: string; + server?: ComposioServer; } -const KlavisServerItem = memo( - ({ identifier, label, server, serverName, icon }) => { - const { isWaitingAuth, openOAuthWindow } = useKlavisOAuth({ +const ComposioServerItem = memo( + ({ identifier, label, server, appSlug, icon }) => { + const { isWaitingAuth, openOAuthWindow } = useComposioOAuth({ serverStatus: server?.status, }); - const { isConnecting, handleConnect } = useKlavisServerActions({ + const { isConnecting, handleConnect, handleReauthorize } = useComposioServerActions({ + appSlug, identifier, + label, onAuthRequired: openOAuthWindow, server, - serverName, }); - const isConnected = server?.status === KlavisServerStatus.CONNECTED; - const isPendingAuth = server?.status === KlavisServerStatus.PENDING_AUTH; + const isConnected = server?.status === ComposioServerStatus.ACTIVE; + const isPendingAuth = server?.status === ComposioServerStatus.PENDING_AUTH; + const isError = server?.status === ComposioServerStatus.ERROR; const isClickable = !isConnected; const handleItemClick = () => { @@ -43,8 +45,9 @@ const KlavisServerItem = memo( if (!server) { handleConnect(); - } else if (isPendingAuth && server.oauthUrl) { - openOAuthWindow(server.oauthUrl, server.identifier); + } else if (isPendingAuth || isError) { + // Mint a fresh link rather than reopening the (likely expired) one. + handleReauthorize(); } }; @@ -90,6 +93,6 @@ const KlavisServerItem = memo( }, ); -KlavisServerItem.displayName = 'KlavisServerItem'; +ComposioServerItem.displayName = 'ComposioServerItem'; -export default KlavisServerItem; +export default ComposioServerItem; diff --git a/src/routes/onboarding/components/KlavisServerList/components/ServerIcon.tsx b/src/routes/onboarding/components/ComposioServerList/components/ServerIcon.tsx similarity index 100% rename from src/routes/onboarding/components/KlavisServerList/components/ServerIcon.tsx rename to src/routes/onboarding/components/ComposioServerList/components/ServerIcon.tsx diff --git a/src/routes/onboarding/components/KlavisServerList/components/ServerStatusControl.tsx b/src/routes/onboarding/components/ComposioServerList/components/ServerStatusControl.tsx similarity index 75% rename from src/routes/onboarding/components/KlavisServerList/components/ServerStatusControl.tsx rename to src/routes/onboarding/components/ComposioServerList/components/ServerStatusControl.tsx index bccbf14d03a..feb08800bee 100644 --- a/src/routes/onboarding/components/KlavisServerList/components/ServerStatusControl.tsx +++ b/src/routes/onboarding/components/ComposioServerList/components/ServerStatusControl.tsx @@ -4,13 +4,13 @@ import { CheckIcon, CircleX, Loader2 } from 'lucide-react'; import { memo } from 'react'; import { useTranslation } from 'react-i18next'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { type ComposioServer } from '@/store/tool/slices/composioStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; interface ServerStatusControlProps { isConnecting: boolean; isWaitingAuth: boolean; - server?: KlavisServer; + server?: ComposioServer; } const ServerStatusControl = memo( @@ -29,20 +29,20 @@ const ServerStatusControl = memo( // Server status indicators switch (server.status) { - case KlavisServerStatus.CONNECTED: { + case ComposioServerStatus.ACTIVE: { return ; } - case KlavisServerStatus.PENDING_AUTH: { + case ComposioServerStatus.PENDING_AUTH: { return null; } - case KlavisServerStatus.ERROR: { + case ComposioServerStatus.ERROR: { return ( ); } diff --git a/src/routes/onboarding/components/KlavisServerList/hooks/useKlavisOAuth.ts b/src/routes/onboarding/components/ComposioServerList/hooks/useComposioOAuth.ts similarity index 82% rename from src/routes/onboarding/components/KlavisServerList/hooks/useKlavisOAuth.ts rename to src/routes/onboarding/components/ComposioServerList/hooks/useComposioOAuth.ts index 487c5c3d605..8300f7f3d54 100644 --- a/src/routes/onboarding/components/KlavisServerList/hooks/useKlavisOAuth.ts +++ b/src/routes/onboarding/components/ComposioServerList/hooks/useComposioOAuth.ts @@ -1,17 +1,17 @@ import { useCallback, useEffect, useRef, useState } from 'react'; import { useToolStore } from '@/store/tool'; -import { KlavisServerStatus } from '@/store/tool/slices/klavisStore'; +import { ComposioServerStatus } from '@/store/tool/slices/composioStore'; const POLL_INTERVAL_MS = 1000; const POLL_TIMEOUT_MS = 15_000; const WINDOW_CLOSED_POLL_TIMEOUT_MS = 4000; // Shorter timeout when window is closed -interface UseKlavisOAuthProps { - serverStatus?: KlavisServerStatus; +interface UseComposioOAuthProps { + serverStatus?: ComposioServerStatus; } -export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { +export const useComposioOAuth = ({ serverStatus }: UseComposioOAuthProps) => { const [isWaitingAuth, setIsWaitingAuth] = useState(false); const oauthWindowRef = useRef(null); @@ -19,7 +19,7 @@ export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { const pollIntervalRef = useRef | null>(null); const pollTimeoutRef = useRef | null>(null); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); const cleanup = useCallback(() => { if (windowCheckIntervalRef.current) { @@ -45,7 +45,7 @@ export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { }, [cleanup]); useEffect(() => { - if (serverStatus === KlavisServerStatus.CONNECTED && isWaitingAuth) { + if (serverStatus === ComposioServerStatus.ACTIVE && isWaitingAuth) { cleanup(); } }, [serverStatus, isWaitingAuth, cleanup]); @@ -56,9 +56,9 @@ export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { pollIntervalRef.current = setInterval(async () => { try { - await refreshKlavisServerTools(serverName); + await refreshComposioConnectionStatus(serverName); } catch (error) { - console.info('[Klavis] Polling check (expected during auth):', error); + console.info('[Composio] Polling check (expected during auth):', error); } }, POLL_INTERVAL_MS); @@ -70,7 +70,7 @@ export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { setIsWaitingAuth(false); }, timeoutMs); }, - [refreshKlavisServerTools], + [refreshComposioConnectionStatus], ); const startWindowMonitor = useCallback( @@ -104,11 +104,11 @@ export const useKlavisOAuth = ({ serverStatus }: UseKlavisOAuthProps) => { ); const openOAuthWindow = useCallback( - (oauthUrl: string, serverName: string) => { + (redirectUrl: string, serverName: string) => { cleanup(); setIsWaitingAuth(true); - const oauthWindow = window.open(oauthUrl, '_blank', 'width=600,height=700'); + const oauthWindow = window.open(redirectUrl, '_blank', 'width=600,height=700'); if (oauthWindow) { oauthWindowRef.current = oauthWindow; startWindowMonitor(oauthWindow, serverName); diff --git a/src/routes/onboarding/components/ComposioServerList/hooks/useComposioServerActions.ts b/src/routes/onboarding/components/ComposioServerList/hooks/useComposioServerActions.ts new file mode 100644 index 00000000000..fb221057edd --- /dev/null +++ b/src/routes/onboarding/components/ComposioServerList/hooks/useComposioServerActions.ts @@ -0,0 +1,80 @@ +import { useState } from 'react'; + +import { useToolStore } from '@/store/tool'; +import { type ComposioServer, ComposioServerStatus } from '@/store/tool/slices/composioStore'; +import { useUserStore } from '@/store/user'; + +interface UseComposioServerActionsProps { + appSlug: string; + identifier: string; + label: string; + onAuthRequired?: (redirectUrl: string, serverIdentifier: string) => void; + server?: ComposioServer; +} + +export const useComposioServerActions = ({ + identifier, + appSlug, + label, + server, + onAuthRequired, +}: UseComposioServerActionsProps) => { + const [isConnecting, setIsConnecting] = useState(false); + + const createComposioConnection = useToolStore((s) => s.createComposioConnection); + const refreshComposioConnectionStatus = useToolStore((s) => s.refreshComposioConnectionStatus); + const reauthorizeComposioConnection = useToolStore((s) => s.reauthorizeComposioConnection); + const toggleDefaultPlugin = useUserStore((s) => s.toggleInboxAgentDefaultPlugin); + + const handleConnect = async () => { + if (server) return; + + setIsConnecting(true); + try { + const newServer = await createComposioConnection({ + appSlug, + identifier, + label, + }); + + if (newServer) { + const newPluginId = newServer.identifier; + await toggleDefaultPlugin(newPluginId); + + if (newServer.status === ComposioServerStatus.ACTIVE) { + await refreshComposioConnectionStatus(newServer.identifier); + } else if (newServer.redirectUrl) { + onAuthRequired?.(newServer.redirectUrl, newServer.identifier); + } + } + } catch (error) { + console.error('[Composio] Failed to connect server:', error); + } finally { + setIsConnecting(false); + } + }; + + // Re-mint a fresh link (the prior one likely expired) instead of reopening the + // stale redirectUrl, so a pending/errored row can always be retried. + const handleReauthorize = async () => { + if (!server) return; + + setIsConnecting(true); + try { + const newServer = await reauthorizeComposioConnection(server.identifier); + if (newServer?.redirectUrl) { + onAuthRequired?.(newServer.redirectUrl, newServer.identifier); + } + } catch (error) { + console.error('[Composio] Failed to re-authorize server:', error); + } finally { + setIsConnecting(false); + } + }; + + return { + handleConnect, + handleReauthorize, + isConnecting, + }; +}; diff --git a/src/routes/onboarding/components/ComposioServerList/index.tsx b/src/routes/onboarding/components/ComposioServerList/index.tsx new file mode 100644 index 00000000000..1c641adc5c5 --- /dev/null +++ b/src/routes/onboarding/components/ComposioServerList/index.tsx @@ -0,0 +1,43 @@ +'use client'; + +import { Grid, ScrollShadow } from '@lobehub/ui'; +import isEqual from 'fast-deep-equal'; +import { memo } from 'react'; + +import { COMPOSIO_APP_TYPES } from '@/const/index'; +import { useToolStore } from '@/store/tool'; +import { composioStoreSelectors } from '@/store/tool/slices/composioStore'; + +import ComposioServerItem from './components/ComposioServerItem'; + +const ComposioServerList = memo(() => { + const allComposioServers = useToolStore(composioStoreSelectors.getServers, isEqual); + const useFetchUserComposioConnections = useToolStore((s) => s.useFetchUserComposioConnections); + + useFetchUserComposioConnections(true); + + const getServerByIdentifier = (identifier: string) => { + return allComposioServers.find((server) => server.identifier === identifier); + }; + + return ( + + + {COMPOSIO_APP_TYPES.map((type) => ( + + ))} + + + ); +}); + +ComposioServerList.displayName = 'ComposioServerList'; + +export default ComposioServerList; diff --git a/src/routes/onboarding/components/KlavisServerList/hooks/useKlavisServerActions.ts b/src/routes/onboarding/components/KlavisServerList/hooks/useKlavisServerActions.ts deleted file mode 100644 index f26df1eb107..00000000000 --- a/src/routes/onboarding/components/KlavisServerList/hooks/useKlavisServerActions.ts +++ /dev/null @@ -1,60 +0,0 @@ -import { useState } from 'react'; - -import { useToolStore } from '@/store/tool'; -import { type KlavisServer } from '@/store/tool/slices/klavisStore'; -import { useUserStore } from '@/store/user'; -import { userProfileSelectors } from '@/store/user/selectors'; - -interface UseKlavisServerActionsProps { - identifier: string; - onAuthRequired?: (oauthUrl: string, serverIdentifier: string) => void; - server?: KlavisServer; - serverName: string; -} - -export const useKlavisServerActions = ({ - identifier, - serverName, - server, - onAuthRequired, -}: UseKlavisServerActionsProps) => { - const [isConnecting, setIsConnecting] = useState(false); - - const userId = useUserStore(userProfileSelectors.userId); - const createKlavisServer = useToolStore((s) => s.createKlavisServer); - const refreshKlavisServerTools = useToolStore((s) => s.refreshKlavisServerTools); - const toggleDefaultPlugin = useUserStore((s) => s.toggleInboxAgentDefaultPlugin); - - const handleConnect = async () => { - if (!userId || server) return; - - setIsConnecting(true); - try { - const newServer = await createKlavisServer({ - identifier, - serverName, - userId, - }); - - if (newServer) { - const newPluginId = newServer.identifier; - await toggleDefaultPlugin(newPluginId); - - if (newServer.isAuthenticated) { - await refreshKlavisServerTools(newServer.identifier); - } else if (newServer.oauthUrl) { - onAuthRequired?.(newServer.oauthUrl, newServer.identifier); - } - } - } catch (error) { - console.error('[Klavis] Failed to connect server:', error); - } finally { - setIsConnecting(false); - } - }; - - return { - handleConnect, - isConnecting, - }; -}; diff --git a/src/routes/onboarding/components/KlavisServerList/index.tsx b/src/routes/onboarding/components/KlavisServerList/index.tsx deleted file mode 100644 index 7f88546bfc4..00000000000 --- a/src/routes/onboarding/components/KlavisServerList/index.tsx +++ /dev/null @@ -1,43 +0,0 @@ -'use client'; - -import { Grid, ScrollShadow } from '@lobehub/ui'; -import isEqual from 'fast-deep-equal'; -import { memo } from 'react'; - -import { KLAVIS_SERVER_TYPES } from '@/const/index'; -import { useToolStore } from '@/store/tool'; -import { klavisStoreSelectors } from '@/store/tool/slices/klavisStore'; - -import KlavisServerItem from './components/KlavisServerItem'; - -const KlavisServerList = memo(() => { - const allKlavisServers = useToolStore(klavisStoreSelectors.getServers, isEqual); - const useFetchUserKlavisServers = useToolStore((s) => s.useFetchUserKlavisServers); - - useFetchUserKlavisServers(true); - - const getServerByIdentifier = (identifier: string) => { - return allKlavisServers.find((server) => server.identifier === identifier); - }; - - return ( - - - {KLAVIS_SERVER_TYPES.map((type) => ( - - ))} - - - ); -}); - -KlavisServerList.displayName = 'KlavisServerList'; - -export default KlavisServerList; diff --git a/src/routes/onboarding/features/ProSettingsStep.test.tsx b/src/routes/onboarding/features/ProSettingsStep.test.tsx index a7825760775..18a2fa279be 100644 --- a/src/routes/onboarding/features/ProSettingsStep.test.tsx +++ b/src/routes/onboarding/features/ProSettingsStep.test.tsx @@ -25,11 +25,11 @@ vi.mock('react-i18next', () => ({ useTranslation: () => ({ t: (key: string) => ( - { - back: 'Back', - next: 'Next', + ({ + 'back': 'Back', + 'next': 'Next', 'proSettings.connectors.title': 'Connect Your Favorite Tools', - } as Record + }) as Record )[key] ?? key, }), })); @@ -38,8 +38,8 @@ vi.mock('@/routes/onboarding/components/LobeMessage', () => ({ default: ({ sentences }: { sentences: string[] }) =>
{sentences.join(' / ')}
, })); -vi.mock('../components/KlavisServerList', () => ({ - default: () =>
KlavisServerList
, +vi.mock('../components/ComposioServerList', () => ({ + default: () =>
ComposioServerList
, })); afterEach(() => { @@ -47,11 +47,11 @@ afterEach(() => { }); describe('ProSettingsStep', () => { - it('uses the connector title as the step title and renders the Klavis server list', () => { + it('uses the connector title as the step title and renders the Composio server list', () => { render(); expect(screen.getAllByText('Connect Your Favorite Tools')).toHaveLength(1); - expect(screen.getByText('KlavisServerList')).toBeInTheDocument(); + expect(screen.getByText('ComposioServerList')).toBeInTheDocument(); }); it('calls the provided navigation handlers', () => { diff --git a/src/routes/onboarding/features/ProSettingsStep.tsx b/src/routes/onboarding/features/ProSettingsStep.tsx index 1c6fec998d1..85566270d5b 100644 --- a/src/routes/onboarding/features/ProSettingsStep.tsx +++ b/src/routes/onboarding/features/ProSettingsStep.tsx @@ -8,7 +8,7 @@ import { useTranslation } from 'react-i18next'; import LobeMessage from '@/routes/onboarding/components/LobeMessage'; -import KlavisServerList from '../components/KlavisServerList'; +import ComposioServerList from '../components/ComposioServerList'; interface ProSettingsStepProps { onBack: () => void; @@ -39,7 +39,7 @@ const ProSettingsStep = memo(({ onBack, onNext }) => { - +