# Copyright 2026 zhaoxi826 # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. from pydantic import BaseModel import viceroy from pretor.utils.ray_hook import ray_actor_hook from fastapi import APIRouter, Depends from pretor.utils.access import TokenData from pretor.utils.check_user.role_check import RoleChecker from pretor.core.postgres_database.table import UserAuthority resource_router = APIRouter(prefix="/api/v1/resource") class Skill(BaseModel): """Skill 核心组件类。 这是一个领域数据模型或功能封装类,承载了 Skill 相关的内聚属性定义与状态维护。它的存在隔离了局部的业务复杂性,并对外提供了类型安全的访问接口。""" repo_url: str path: str | None @resource_router.post("/skill") async def install_skill( skill: Skill, _: TokenData = Depends(RoleChecker(allowed_roles=UserAuthority.USER)) ): """处理针对 install skill 相关的 HTTP API 请求。 该接口负责解析前端传入的载荷数据,调用底层核心业务逻辑进行处理,并组装标准化的 JSON 响应。 Args: skill (Skill): 参与 install skill 逻辑运算或数据构建的上下文依赖对象。 _ (TokenData): 参与 install skill 逻辑运算或数据构建的上下文依赖对象。 Returns: : 序列化后的标准网络响应模型(如包含业务状态码、成功标志及对应的数据载荷 Data)。""" global_state_machine = ray_actor_hook("global_state_machine").global_state_machine # noinspection PyUnresolvedReferences import os skill_output_dir = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", "plugin", "skill") ) os.makedirs(skill_output_dir, exist_ok=True) await viceroy.install_skill_async( url=skill.repo_url, path=skill.path, output=skill_output_dir ) if skill.path: skill_name = skill.path.split("/")[-1] else: skill_name = skill.repo_url.split("/")[-1] await global_state_machine.add_skill.remote(skill_name) return {"message": "创建成功"} @resource_router.get("/skill") async def get_skills( _: TokenData = Depends(RoleChecker(allowed_roles=UserAuthority.USER)), ): """处理针对 get skills 相关的 HTTP API 请求。 该接口负责解析前端传入的载荷数据,调用底层核心业务逻辑进行处理,并组装标准化的 JSON 响应。 Args: _ (TokenData): 参与 get skills 逻辑运算或数据构建的上下文依赖对象。 Returns: : 序列化后的标准网络响应模型(如包含业务状态码、成功标志及对应的数据载荷 Data)。""" global_state_machine = ray_actor_hook("global_state_machine").global_state_machine skills = await global_state_machine.get_skill_list.remote() return {"skills": skills} @resource_router.delete("/skill/{skill_name}") async def delete_skill( skill_name: str, _: TokenData = Depends( RoleChecker(allowed_roles=UserAuthority.SUPER_ADMINISTRATOR) ), ): """处理针对 delete skill 相关的 HTTP API 请求。 该接口负责解析前端传入的载荷数据,调用底层核心业务逻辑进行处理,并组装标准化的 JSON 响应。 Args: skill_name (str): 赋予该实体的人类可读名称或标题字符串,主要用于前端 UI 展示、日志记录或模糊检索。 _ (TokenData): 参与 delete skill 逻辑运算或数据构建的上下文依赖对象。 Returns: : 序列化后的标准网络响应模型(如包含业务状态码、成功标志及对应的数据载荷 Data)。""" global_state_machine = ray_actor_hook("global_state_machine").global_state_machine # Note: this only removes it from the state machine manager. await global_state_machine.remove_skill.remote(skill_name) return {"message": "success"} @resource_router.get("/tool") async def get_tools( _: TokenData = Depends(RoleChecker(allowed_roles=UserAuthority.USER)), ): """处理针对 get tools 相关的 HTTP API 请求。 该接口负责解析前端传入的载荷数据,调用底层核心业务逻辑进行处理,并组装标准化的 JSON 响应。 Args: _ (TokenData): 参与 get tools 逻辑运算或数据构建的上下文依赖对象。 Returns: : 序列化后的标准网络响应模型(如包含业务状态码、成功标志及对应的数据载荷 Data)。""" global_state_machine = ray_actor_hook("global_state_machine").global_state_machine tool_mapper = await global_state_machine.get_tool_mapper.remote() all_tool_names = set() for scope_tools in tool_mapper.values(): all_tool_names.update(scope_tools.keys()) return {"tools": list(all_tool_names)}