diff --git a/backend/app/utils/agent.py b/backend/app/utils/agent.py index 61afc359b..da31f53c1 100644 --- a/backend/app/utils/agent.py +++ b/backend/app/utils/agent.py @@ -47,6 +47,7 @@ from app.utils.toolkit.twitter_toolkit import TwitterToolkit from app.utils.toolkit.linkedin_toolkit import LinkedInToolkit from app.utils.toolkit.reddit_toolkit import RedditToolkit from app.utils.toolkit.slack_toolkit import SlackToolkit +from app.utils.toolkit.lark_toolkit import LarkToolkit from camel.types import ModelPlatformType, ModelType from camel.toolkits import MCPToolkit, ToolkitMessageIntegration import datetime @@ -1598,6 +1599,7 @@ async def get_toolkits(tools: list[str], agent_name: str, api_task_id: str): "google_gmail_mcp_toolkit": GoogleGmailMCPToolkit, "image_analysis_toolkit": ImageAnalysisToolkit, "linkedin_toolkit": LinkedInToolkit, + "lark_toolkit": LarkToolkit, "mcp_search_toolkit": McpSearchToolkit, "notion_mcp_toolkit": NotionMCPToolkit, "pptx_toolkit": PPTXToolkit, diff --git a/backend/app/utils/toolkit/lark_toolkit.py b/backend/app/utils/toolkit/lark_toolkit.py new file mode 100644 index 000000000..6aa864e3d --- /dev/null +++ b/backend/app/utils/toolkit/lark_toolkit.py @@ -0,0 +1,22 @@ +from camel.toolkits import LarkToolkit as BaseLarkToolkit +from camel.toolkits.function_tool import FunctionTool + +from app.component.environment import env +from app.service.task import Agents +from app.utils.listen.toolkit_listen import auto_listen_toolkit +from app.utils.toolkit.abstract_toolkit import AbstractToolkit + + +@auto_listen_toolkit(BaseLarkToolkit) +class LarkToolkit(BaseLarkToolkit, AbstractToolkit): + agent_name: str = Agents.social_medium_agent + + def __init__(self, api_task_id: str, timeout: float | None = None): + super().__init__(timeout=timeout) + self.api_task_id = api_task_id + + @classmethod + def get_can_use_tools(cls, api_task_id: str) -> list[FunctionTool]: + if env("LARK_APP_ID") and env("LARK_APP_SECRET"): + return LarkToolkit(api_task_id).get_tools() + return [] diff --git a/server/app/model/config/config.py b/server/app/model/config/config.py index 4677b4e82..5e8dcd1b9 100644 --- a/server/app/model/config/config.py +++ b/server/app/model/config/config.py @@ -39,14 +39,18 @@ class ConfigInfo: # "env_vars": [], # "toolkit": "", # }, - ConfigGroup.SLACK.value: { - "env_vars": ["SLACK_BOT_TOKEN"], - "toolkit": "slack_toolkit", - }, - ConfigGroup.NOTION.value: { - "env_vars": ["MCP_REMOTE_CONFIG_DIR"], - "toolkit": "notion_mcp_toolkit", - }, + ConfigGroup.SLACK.value: { + "env_vars": ["SLACK_BOT_TOKEN"], + "toolkit": "slack_toolkit", + }, + ConfigGroup.LARK.value: { + "env_vars": ["LARK_APP_ID", "LARK_APP_SECRET"], + "toolkit": "lark_toolkit", + }, + ConfigGroup.NOTION.value: { + "env_vars": ["MCP_REMOTE_CONFIG_DIR"], + "toolkit": "notion_mcp_toolkit", + }, ConfigGroup.TWITTER.value: { "env_vars": [ "TWITTER_CONSUMER_KEY", diff --git a/server/app/type/config_group.py b/server/app/type/config_group.py index df5103e64..28fcc4d39 100644 --- a/server/app/type/config_group.py +++ b/server/app/type/config_group.py @@ -1,15 +1,16 @@ from enum import Enum -class ConfigGroup(str, Enum): - WHATSAPP = "WhatsApp" - TWITTER = "X(Twitter)" - LINKEDIN = "LinkedIn" - REDDIT = "Reddit" - SLACK = "Slack" - NOTION = "Notion" - GOOGLE_SUITE = "GoogleSuite" - DISCORD = "Discord" +class ConfigGroup(str, Enum): + WHATSAPP = "WhatsApp" + TWITTER = "X(Twitter)" + LINKEDIN = "LinkedIn" + REDDIT = "Reddit" + SLACK = "Slack" + LARK = "Lark" + NOTION = "Notion" + GOOGLE_SUITE = "GoogleSuite" + DISCORD = "Discord" SEARCH = "Search" AUDIO_ANALYSIS = "Audio Analysis" CODE_EXECUTION = "Code Execution" diff --git a/src/components/AddWorker/ToolSelect.tsx b/src/components/AddWorker/ToolSelect.tsx index 92922f92e..e94b3364c 100644 --- a/src/components/AddWorker/ToolSelect.tsx +++ b/src/components/AddWorker/ToolSelect.tsx @@ -337,10 +337,31 @@ const ToolSelect = forwardRef< // Continue anyway to trigger installation } - // Trigger instantiation for Google Calendar - if (activeMcp.key === "Google Calendar") { - console.log("[ToolSelect installMcp] Starting Google Calendar installation"); - try { + if (activeMcp.key !== "Google Calendar") { + const integrationItem = integrations.find( + (item) => item.key === activeMcp.key + ); + addOption( + { + id: activeMcp.id, + key: activeMcp.key, + name: activeMcp.name ?? activeMcp.key, + description: + typeof integrationItem?.desc === "string" + ? integrationItem.desc + : "", + toolkit: integrationItem?.toolkit, + isLocal: true, + }, + true + ); + return; + } + + // Trigger instantiation for Google Calendar + if (activeMcp.key === "Google Calendar") { + console.log("[ToolSelect installMcp] Starting Google Calendar installation"); + try { const response = await fetchPost("/install/tool/google_calendar"); if (response.success) { diff --git a/src/components/AddWorker/index.tsx b/src/components/AddWorker/index.tsx index 7393c5982..c06d8cd76 100644 --- a/src/components/AddWorker/index.tsx +++ b/src/components/AddWorker/index.tsx @@ -164,7 +164,11 @@ export function AddWorker({ // call ToolSelect's install method if (toolSelectRef.current) { try { - if (activeMcp.key === "EXA Search" || activeMcp.key === "Google Calendar") { + if ( + activeMcp.key === "EXA Search" || + activeMcp.key === "Google Calendar" || + activeMcp.key === "Lark" + ) { await toolSelectRef.current.installMcp( activeMcp.id, { ...envValues }, diff --git a/src/components/IntegrationList/index.tsx b/src/components/IntegrationList/index.tsx index 24098f960..4ee29e034 100644 --- a/src/components/IntegrationList/index.tsx +++ b/src/components/IntegrationList/index.tsx @@ -88,8 +88,8 @@ export default function IntegrationList({ console.log(item); const searchKey = isSelectMode ? "EXA Search" : "Search"; - if (item.key === searchKey) { - const mcp = createMcpFromItem(item, 13); + if (item.key === searchKey || item.key === "Lark") { + const mcp = createMcpFromItem(item, item.key === "Lark" ? 15 : 13); if (isSelectMode) { onShowEnvConfig?.(mcp); } else {