本次提交包含多项代码优化与规范修正: 1. 文档与注释优化:修正注释术语、补充注解与FR编号 2. 代码格式调整:统一空格、换行与缩进规范 3. 类型与接口完善:补充__all__导出、修正返回类型注解 4. 错误处理增强:新增领域错误类与校验逻辑 5. 依赖与导入调整:修复路径引用、统一时区导入 6. 协议与契约更新:完善接口文档与一致性注解
140 lines
4.9 KiB
Python
140 lines
4.9 KiB
Python
"""渠道工具 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
|