2026-07-02 03:22:12 +08:00
|
|
|
|
"""渠道工具 DTO。
|
|
|
|
|
|
|
|
|
|
|
|
定义渠道工具相关的不可变值对象,包括工具参数、渠道工具、工具定义与
|
|
|
|
|
|
工具结果。所有 DTO 均为 ``dataclass(frozen=True)``,仅依赖标准库,
|
|
|
|
|
|
用于 FR-11 渠道工具注册与 FR-12 工具调用结果回传。集合字段使用 tuple
|
|
|
|
|
|
以保证 frozen dataclass 的不可变语义。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
|
|
from dataclasses import dataclass
|
2026-07-03 19:18:13 +08:00
|
|
|
|
from typing import Any, Literal
|
|
|
|
|
|
|
|
|
|
|
|
from yuxi.channels.contract.errors import ValidationError
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class ToolParameter:
|
|
|
|
|
|
"""工具参数。
|
|
|
|
|
|
|
|
|
|
|
|
描述渠道工具的单个参数元信息,包括名称、类型、描述、是否必填与默认值,
|
|
|
|
|
|
由适配器按渠道协议解析后填充,用于工具调用前的参数校验。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
name: 参数名称。
|
|
|
|
|
|
type: 参数类型(str | int | bool | json)。
|
|
|
|
|
|
description: 参数描述。
|
|
|
|
|
|
required: 是否必填(默认 True)。
|
|
|
|
|
|
default: 默认值(默认 None)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
name: str
|
2026-07-03 19:18:13 +08:00
|
|
|
|
type: Literal["str", "int", "bool", "json"]
|
2026-07-02 03:22:12 +08:00
|
|
|
|
description: str
|
|
|
|
|
|
required: bool = True
|
|
|
|
|
|
default: Any = None
|
|
|
|
|
|
|
2026-07-03 19:18:13 +08:00
|
|
|
|
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")
|
|
|
|
|
|
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
@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, ...] = ()
|
2026-07-03 19:18:13 +08:00
|
|
|
|
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")
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@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]
|
2026-07-03 19:18:13 +08:00
|
|
|
|
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")
|
2026-07-02 03:22:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
|
|
|
|
class ToolResult:
|
|
|
|
|
|
"""工具结果。
|
|
|
|
|
|
|
|
|
|
|
|
描述工具调用的执行结果,包括是否成功、结果数据与错误信息,用于
|
|
|
|
|
|
FR-12 工具调用结果回传。
|
|
|
|
|
|
|
|
|
|
|
|
字段:
|
|
|
|
|
|
success: 是否成功。
|
|
|
|
|
|
result: 结果数据(默认 None)。
|
|
|
|
|
|
error: 错误信息(可选,默认 None)。
|
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
success: bool
|
|
|
|
|
|
result: Any = None
|
|
|
|
|
|
error: str | None = None
|