"""渠道工具 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