ForcePilot/backend/package/yuxi/channels/contract/dtos/tools.py
Kris 00092c818e chore: 批量代码优化与规范完善
本次提交包含多项代码优化与规范修正:
1. 文档与注释优化:修正注释术语、补充注解与FR编号
2. 代码格式调整:统一空格、换行与缩进规范
3. 类型与接口完善:补充__all__导出、修正返回类型注解
4. 错误处理增强:新增领域错误类与校验逻辑
5. 依赖与导入调整:修复路径引用、统一时区导入
6. 协议与契约更新:完善接口文档与一致性注解
2026-07-03 19:18:13 +08:00

140 lines
4.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""渠道工具 DTO。
定义渠道工具相关的不可变值对象,包括工具参数、渠道工具、工具定义与
工具结果。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库,
用于 FR-11 渠道工具注册与 FR-12 工具调用结果回传。集合字段使用 tuple
以保证 frozen dataclass 的不可变语义。
"""
from __future__ import annotations
from dataclasses import dataclass
from typing import Any, Literal
from yuxi.channels.contract.errors import ValidationError
@dataclass(frozen=True)
class ToolParameter:
"""工具参数。
描述渠道工具的单个参数元信息,包括名称、类型、描述、是否必填与默认值,
由适配器按渠道协议解析后填充,用于工具调用前的参数校验。
字段:
name: 参数名称。
type: 参数类型str | int | bool | json
description: 参数描述。
required: 是否必填(默认 True
default: 默认值(默认 None
"""
name: str
type: Literal["str", "int", "bool", "json"]
description: str
required: bool = True
default: Any = None
def __post_init__(self) -> None:
"""校验 name 非空与 type 取值合法。
``name`` 必须非空,``type`` 必须为 ``str`` / ``int`` / ``bool`` /
``json`` 之一,在构造时即抛出 ``ValidationError``,避免空参数名或
非法类型导致工具参数校验失效INV-8
"""
if not self.name:
raise ValidationError("name", "must not be empty")
if self.type not in ("str", "int", "bool", "json"):
raise ValidationError("type", "must be one of str, int, bool, json")
@dataclass(frozen=True)
class ChannelTool:
"""渠道工具。
描述由插件注册至渠道的工具,包括名称、描述、参数列表、处理函数标识
与作用范围,用于 FR-11 渠道工具注册。集合字段使用 tuple 以保证
frozen dataclass 的不可变语义。
字段:
name: 工具名称。
description: 工具描述。
handler_id: 插件提供的处理函数标识。
parameters: 参数列表(默认空 tuple
scope: 作用范围private | group | all默认 all
"""
name: str
description: str
handler_id: str
parameters: tuple[ToolParameter, ...] = ()
scope: Literal["private", "group", "all"] = "all"
def __post_init__(self) -> None:
"""校验 name / description / handler_id 非空与 scope 取值合法。
必填字符串字段必须非空,``scope`` 必须为 ``private`` / ``group`` /
``all`` 之一,在构造时即抛出 ``ValidationError``,避免空标识或非法
作用范围导致工具注册失效INV-8
"""
if not self.name:
raise ValidationError("name", "must not be empty")
if not self.description:
raise ValidationError("description", "must not be empty")
if not self.handler_id:
raise ValidationError("handler_id", "must not be empty")
if self.scope not in ("private", "group", "all"):
raise ValidationError("scope", "must be one of private, group, all")
@dataclass(frozen=True)
class ToolDefinition:
"""工具定义。
描述工具的声明式定义包括名称、描述、JSON Schema 参数模型与作用范围,
用于工具注册中心对外暴露工具元信息。
字段:
name: 工具名称。
description: 工具描述。
parameters_schema: 参数 JSON Schema。
scope: 作用范围private | group | all默认 all
"""
name: str
description: str
parameters_schema: dict[str, Any]
scope: Literal["private", "group", "all"] = "all"
def __post_init__(self) -> None:
"""校验 name / description 非空与 scope 取值合法。
``name`` 与 ``description`` 必须非空,``scope`` 必须为 ``private`` /
``group`` / ``all`` 之一,在构造时即抛出 ``ValidationError``,避免
空标识或非法作用范围导致工具元信息暴露失效INV-8
"""
if not self.name:
raise ValidationError("name", "must not be empty")
if not self.description:
raise ValidationError("description", "must not be empty")
if self.scope not in ("private", "group", "all"):
raise ValidationError("scope", "must be one of private, group, all")
@dataclass(frozen=True)
class ToolResult:
"""工具结果。
描述工具调用的执行结果,包括是否成功、结果数据与错误信息,用于
FR-12 工具调用结果回传。
字段:
success: 是否成功。
result: 结果数据(默认 None
error: 错误信息(可选,默认 None
"""
success: bool
result: Any = None
error: str | None = None