diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 98a1757..95cd52f 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -6,6 +6,7 @@ import { SetupGuideModal } from './components/Layout/SetupGuideModal'; import { SettingsLayout } from './components/Settings/SettingsLayout'; import { AgentLayout } from './components/Agent/AgentLayout'; import { PluginLayout } from './components/Plugin/PluginLayout'; +import { ToolSettings } from './components/Plugin/ToolSettings'; import { WorkflowConfigSettings } from './components/Agent/WorkflowConfigSettings'; import { SystemLogsView } from './components/Agent/SystemLogsView'; import { LeftPanel } from './components/Chat/LeftPanel'; @@ -97,6 +98,12 @@ function App() { {mode === 'agent' && agentTab === 'agents' && } + {mode === 'agent' && agentTab === 'toolsets' && ( +
+ +
+ )} + {mode === 'agent' && agentTab === 'plugin' && } {mode === 'agent' && agentTab === 'config' && ( diff --git a/frontend/src/components/Layout/CollapsibleSidebar.tsx b/frontend/src/components/Layout/CollapsibleSidebar.tsx index 9613ff9..76f885c 100644 --- a/frontend/src/components/Layout/CollapsibleSidebar.tsx +++ b/frontend/src/components/Layout/CollapsibleSidebar.tsx @@ -1,5 +1,5 @@ import { useTranslation } from 'react-i18next'; -import { MessageSquare, Workflow, Box, Bot, ChevronLeft, ChevronRight, Settings, ScrollText } from 'lucide-react'; +import { MessageSquare, Workflow, Box, Bot, ChevronLeft, ChevronRight, Settings, ScrollText, Wrench } from 'lucide-react'; import { useAppStore } from '../../store/useAppStore'; export function CollapsibleSidebar() { @@ -20,8 +20,9 @@ export function CollapsibleSidebar() { { key: 'workflow', label: t('nav.workflow'), icon: Workflow }, ] : [ - { key: 'plugin', label: t('nav.plugin'), icon: Box }, { key: 'agents', label: t('nav.agents'), icon: Bot }, + { key: 'toolsets', label: t('nav.toolsets'), icon: Wrench }, + { key: 'plugin', label: t('nav.plugin'), icon: Box }, { key: 'config', label: t('nav.config'), icon: Settings }, { key: 'logs', label: t('nav.logs'), icon: ScrollText }, ]; diff --git a/frontend/src/components/Plugin/PluginLayout.tsx b/frontend/src/components/Plugin/PluginLayout.tsx index 8683610..8cb5a6f 100644 --- a/frontend/src/components/Plugin/PluginLayout.tsx +++ b/frontend/src/components/Plugin/PluginLayout.tsx @@ -1,37 +1,16 @@ import { useTranslation } from 'react-i18next'; -import { useAppStore } from '../../store/useAppStore'; import { SkillSettings } from './SkillSettings'; -import { ToolSettings } from './ToolSettings'; export function PluginLayout() { const { t } = useTranslation(); - const { resourceTab, setResourceTab } = useAppStore(); - - const tabs = [ - { key: 'skill', label: t('agent.skills') }, - { key: 'tool', label: t('agent.tools') }, - ]; return (
-
- {tabs.map((tab) => ( - - ))} +
+ {t('plugin.skillManagement')}
- {resourceTab === 'skill' && } - {resourceTab === 'tool' && } +
); diff --git a/frontend/src/i18n/locales/en.json b/frontend/src/i18n/locales/en.json index 35f69de..4dc4774 100644 --- a/frontend/src/i18n/locales/en.json +++ b/frontend/src/i18n/locales/en.json @@ -10,6 +10,7 @@ "workflow": "Workflow", "plugin": "Plugin", "agents": "Agents", + "toolsets": "Toolsets", "config": "Config", "logs": "Logs", "settings": "Settings" diff --git a/frontend/src/i18n/locales/zh.json b/frontend/src/i18n/locales/zh.json index a441eae..9ef1585 100644 --- a/frontend/src/i18n/locales/zh.json +++ b/frontend/src/i18n/locales/zh.json @@ -10,6 +10,7 @@ "workflow": "工作流", "plugin": "插件", "agents": "智能体", + "toolsets": "工具集", "config": "配置", "logs": "日志", "settings": "设置" diff --git a/kilostar/core/global_state_machine/global_state_machine.py b/kilostar/core/global_state_machine/global_state_machine.py index e27f4e4..70362b5 100644 --- a/kilostar/core/global_state_machine/global_state_machine.py +++ b/kilostar/core/global_state_machine/global_state_machine.py @@ -67,14 +67,58 @@ class GlobalStateMachine: # Tool configs cfg_rows = await self.postgres_database.list_tool_configs_db.remote() self._tool_configs = {row["tool_name"]: row["config"] for row in cfg_rows} - # Custom toolsets + # Custom toolsets(含系统预置) ts_rows = await self.postgres_database.list_custom_toolsets.remote() self._custom_toolsets = {row["toolset_id"]: row for row in ts_rows} + # 补种系统预置工具集(首次启动或 DB 被 create_all 重建后) + await self._seed_system_toolsets() # 让 tool_manager 立刻把 custom toolset 装配成 FunctionToolset self._global_tool_manager.rebuild_custom_toolsets(self._custom_toolsets) # 启动期一次性发布 v1 快照,让等待中的读端立刻可用 self._publish_snapshot() + _SYSTEM_TOOLSETS = [ + { + "toolset_id": "system_basic", + "name": "系统基础工具集", + "description": "文件读写、搜索、代码执行等基础能力", + "tools": ["file_reader", "write_file", "edit_file", "search_file", "python_executor", "shell_executor"], + "is_system": True, + "category": "system_basic", + }, + { + "toolset_id": "system_chat", + "name": "系统对话工具集", + "description": "对话场景专用工具(发送文件等)", + "tools": ["send_file"], + "is_system": True, + "category": "system_chat", + }, + { + "toolset_id": "system_workflow", + "name": "系统工作流工具集", + "description": "工作流场景专用工具(审批等)", + "tools": ["approval"], + "is_system": True, + "category": "system_workflow", + }, + ] + + async def _seed_system_toolsets(self): + """若 DB 中缺少系统预置工具集则自动补种。""" + for seed in self._SYSTEM_TOOLSETS: + if seed["toolset_id"] not in self._custom_toolsets: + await self.postgres_database.upsert_custom_toolset.remote( + toolset_id=seed["toolset_id"], + name=seed["name"], + tools=seed["tools"], + description=seed["description"], + owner_id=None, + is_system=True, + category=seed["category"], + ) + self._custom_toolsets[seed["toolset_id"]] = seed + # ─── Snapshot 发布(Object Store 读路径) ──────────────────── def _build_snapshot(self) -> GSMSnapshot: diff --git a/kilostar/core/postgres_database/postgres.py b/kilostar/core/postgres_database/postgres.py index 11a113b..a71ee01 100644 --- a/kilostar/core/postgres_database/postgres.py +++ b/kilostar/core/postgres_database/postgres.py @@ -376,8 +376,10 @@ class PostgresDatabase: tools: list, description: str = None, owner_id: str = None, + is_system: bool = False, + category: str = "user", ): - """插入或更新一个用户自定义工具组。""" + """插入或更新一个工具组(系统预置或用户自定义)。""" await self.ready_event.wait() return await self._custom_toolset_database.upsert( toolset_id=toolset_id, @@ -385,6 +387,8 @@ class PostgresDatabase: tools=tools, description=description, owner_id=owner_id, + is_system=is_system, + category=category, ) async def get_custom_toolset(self, toolset_id: str):