ForcePilot/backend/package/yuxi/channels/contract/dtos/tools.py

140 lines
4.9 KiB
Python
Raw Normal View History

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