mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-18 02:00:09 +08:00
feat: 添加协议模块及消息定义,详细说明新版协议与旧版的差异
This commit is contained in:
@@ -1,3 +1,58 @@
|
||||
"""协议模块。
|
||||
|
||||
定义 AstrBot SDK 的消息协议和描述符,用于插件与核心之间的通信。
|
||||
所有消息均使用 Pydantic 定义,确保类型安全和序列化一致性。
|
||||
|
||||
架构说明:
|
||||
旧版:
|
||||
- 使用标准 JSON-RPC 2.0 协议
|
||||
- 消息类型较少: Request, SuccessResponse, ErrorResponse
|
||||
- 特定请求类型绑定了 AstrMessageEventModel 事件模型
|
||||
- 使用 dataclass 和 pydantic 混合定义
|
||||
|
||||
新版:
|
||||
- 全新的自描述协议,使用 `type` 字段区分消息类型
|
||||
- 更丰富的消息类型: Initialize, Result, Invoke, Event, Cancel
|
||||
- 强大的描述符系统: HandlerDescriptor, CapabilityDescriptor
|
||||
- 多种触发器类型: Command, Message, Event, Schedule
|
||||
- 纯 Pydantic 定义,支持严格验证
|
||||
- 提供 LegacyAdapter 实现新旧协议互操作
|
||||
|
||||
协议消息流程:
|
||||
1. Initialize: 握手建立连接,交换能力和处理器信息
|
||||
2. Invoke: 调用远程能力
|
||||
3. Event: 流式事件通知 (started/delta/completed/failed)
|
||||
4. Result: 调用结果返回
|
||||
5. Cancel: 取消正在进行的调用
|
||||
|
||||
与旧版对比:
|
||||
旧版 JSON-RPC 消息:
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "xxx",
|
||||
"method": "call_handler",
|
||||
"params": {"handler_full_name": "...", "event": {...}}
|
||||
}
|
||||
|
||||
新版协议消息:
|
||||
{
|
||||
"type": "invoke",
|
||||
"id": "xxx",
|
||||
"capability": "handler.invoke",
|
||||
"input": {"handler_id": "...", "event": {...}}
|
||||
}
|
||||
|
||||
TODO: (功能完善):
|
||||
- 添加消息签名验证支持,确保消息来源可信
|
||||
- 添加消息压缩支持,减少大数据传输开销
|
||||
- 添加批量消息支持 (BatchMessage),提高传输效率
|
||||
- 添加消息追踪 ID (trace_id) 支持,便于日志关联
|
||||
- CapabilityDescriptor 缺少 rate_limit 限流配置
|
||||
- HandlerDescriptor 缺少 timeout 超时配置
|
||||
- 缺少心跳消息 (HeartbeatMessage) 支持
|
||||
- 缺少健康检查消息 (HealthCheckMessage) 支持
|
||||
"""
|
||||
|
||||
from .descriptors import CapabilityDescriptor, HandlerDescriptor, Permissions
|
||||
from .messages import (
|
||||
CancelMessage,
|
||||
|
||||
@@ -1,3 +1,41 @@
|
||||
"""描述符模块。
|
||||
|
||||
定义处理器和能力的描述符,用于声明式注册和发现。
|
||||
|
||||
描述符类型概览:
|
||||
HandlerDescriptor: 处理器描述符,描述一个事件处理函数
|
||||
CapabilityDescriptor: 能力描述符,描述一个可调用的远程能力
|
||||
Permissions: 权限配置,控制处理器的访问权限
|
||||
Trigger: 触发器联合类型,支持多种触发方式
|
||||
|
||||
触发器类型:
|
||||
CommandTrigger: 命令触发器,响应特定命令(如 /help)
|
||||
MessageTrigger: 消息触发器,响应匹配正则或关键词的消息
|
||||
EventTrigger: 事件触发器,响应特定类型的事件
|
||||
ScheduleTrigger: 定时触发器,按 cron 或间隔时间执行
|
||||
|
||||
与旧版对比:
|
||||
旧版:
|
||||
- 处理器元信息分散在 handshake 响应中
|
||||
- 使用 event_type 整数区分事件类型
|
||||
- 缺少声明式的触发器定义
|
||||
- 配置通过 extras_configs 字典传递
|
||||
|
||||
新版:
|
||||
- 使用 HandlerDescriptor 统一描述处理器
|
||||
- 使用字符串 event_type,更语义化
|
||||
- 支持多种触发器类型,声明式定义
|
||||
- 使用 Pydantic 模型,类型安全
|
||||
|
||||
TODO:
|
||||
- HandlerDescriptor 缺少 timeout 超时配置
|
||||
- HandlerDescriptor 缺少 retry 重试配置
|
||||
- CapabilityDescriptor 缺少 rate_limit 限流配置
|
||||
- ScheduleTrigger 缺错时错过执行的处理策略
|
||||
- 缺少 HandlerGroupDescriptor 处理器组描述符
|
||||
- 缺少 DependencyDescriptor 依赖声明
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Annotated, Any, Literal
|
||||
@@ -10,11 +48,36 @@ class _DescriptorBase(BaseModel):
|
||||
|
||||
|
||||
class Permissions(_DescriptorBase):
|
||||
"""权限配置,控制处理器的访问权限。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 通过 extras_configs 字典配置
|
||||
{"require_admin": true, "level": 1}
|
||||
新版: 使用 Permissions 模型,类型安全
|
||||
|
||||
Attributes:
|
||||
require_admin: 是否需要管理员权限
|
||||
level: 权限等级,数值越高权限越大
|
||||
"""
|
||||
|
||||
require_admin: bool = False
|
||||
level: int = 0
|
||||
|
||||
|
||||
class CommandTrigger(_DescriptorBase):
|
||||
"""命令触发器,响应特定命令。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 使用 @command_handler("help") 装饰器注册
|
||||
新版: 使用 CommandTrigger 声明式定义,支持别名
|
||||
|
||||
Attributes:
|
||||
type: 触发器类型,固定为 "command"
|
||||
command: 命令名称(不含前缀,如 "help")
|
||||
aliases: 命令别名列表
|
||||
description: 命令描述,用于帮助文档
|
||||
"""
|
||||
|
||||
type: Literal["command"] = "command"
|
||||
command: str
|
||||
aliases: list[str] = Field(default_factory=list)
|
||||
@@ -22,6 +85,19 @@ class CommandTrigger(_DescriptorBase):
|
||||
|
||||
|
||||
class MessageTrigger(_DescriptorBase):
|
||||
"""消息触发器,响应匹配正则或关键词的消息。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 使用 @regex_handler(r"pattern") 或 @message_handler 装饰器
|
||||
新版: 使用 MessageTrigger 声明式定义,支持正则、关键词和平台过滤
|
||||
|
||||
Attributes:
|
||||
type: 触发器类型,固定为 "message"
|
||||
regex: 正则表达式模式,匹配消息文本
|
||||
keywords: 关键词列表,消息包含任一关键词即触发
|
||||
platforms: 目标平台列表,为空表示所有平台
|
||||
"""
|
||||
|
||||
type: Literal["message"] = "message"
|
||||
regex: str | None = None
|
||||
keywords: list[str] = Field(default_factory=list)
|
||||
@@ -29,11 +105,37 @@ class MessageTrigger(_DescriptorBase):
|
||||
|
||||
|
||||
class EventTrigger(_DescriptorBase):
|
||||
"""事件触发器,响应特定类型的事件。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 使用整数 event_type,如 3 表示消息事件
|
||||
新版: 使用字符串 event_type,如 "message" 或 "3",更灵活
|
||||
|
||||
Attributes:
|
||||
type: 触发器类型,固定为 "event"
|
||||
event_type: 事件类型,字符串形式(如 "message"、"notice")
|
||||
"""
|
||||
|
||||
type: Literal["event"] = "event"
|
||||
event_type: str
|
||||
|
||||
|
||||
class ScheduleTrigger(_DescriptorBase):
|
||||
"""定时触发器,按 cron 表达式或固定间隔执行。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 使用 @scheduled("0 * * * *") 装饰器
|
||||
新版: 使用 ScheduleTrigger 声明式定义
|
||||
|
||||
Attributes:
|
||||
type: 触发器类型,固定为 "schedule"
|
||||
cron: cron 表达式(如 "0 9 * * *" 表示每天 9 点)
|
||||
interval_seconds: 执行间隔(秒)
|
||||
|
||||
Note:
|
||||
cron 和 interval_seconds 必须且只能有一个非空。
|
||||
"""
|
||||
|
||||
type: Literal["schedule"] = "schedule"
|
||||
cron: str | None = None
|
||||
interval_seconds: int | None = None
|
||||
@@ -51,9 +153,38 @@ Trigger = Annotated[
|
||||
CommandTrigger | MessageTrigger | EventTrigger | ScheduleTrigger,
|
||||
Field(discriminator="type"),
|
||||
]
|
||||
"""触发器联合类型,使用 type 字段作为判别器自动解析具体类型。"""
|
||||
|
||||
|
||||
class HandlerDescriptor(_DescriptorBase):
|
||||
"""处理器描述符,描述一个事件处理函数的元信息。
|
||||
|
||||
与旧版对比:
|
||||
旧版 handshake 响应中的处理器信息:
|
||||
{
|
||||
"event_type": 3,
|
||||
"handler_full_name": "plugin.handler",
|
||||
"handler_name": "handler",
|
||||
"handler_module_path": "plugin",
|
||||
"desc": "描述",
|
||||
"extras_configs": {"priority": 0, "require_admin": false}
|
||||
}
|
||||
|
||||
新版 HandlerDescriptor:
|
||||
{
|
||||
"id": "plugin.handler",
|
||||
"trigger": {"type": "event", "event_type": "message"},
|
||||
"priority": 0,
|
||||
"permissions": {"require_admin": false, "level": 0}
|
||||
}
|
||||
|
||||
Attributes:
|
||||
id: 处理器唯一标识,通常是 "模块.函数名" 格式
|
||||
trigger: 触发器配置,决定何时执行该处理器
|
||||
priority: 优先级,数值越大越先执行
|
||||
permissions: 权限配置,控制谁可以触发该处理器
|
||||
"""
|
||||
|
||||
id: str
|
||||
trigger: Trigger
|
||||
priority: int = 0
|
||||
@@ -61,6 +192,25 @@ class HandlerDescriptor(_DescriptorBase):
|
||||
|
||||
|
||||
class CapabilityDescriptor(_DescriptorBase):
|
||||
"""能力描述符,描述一个可调用的远程能力。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 无独立的能力描述,通过 method 名称隐式定义
|
||||
新版: 使用 CapabilityDescriptor 显式声明能力,支持 JSON Schema 验证
|
||||
|
||||
能力命名规范:
|
||||
- 使用 "namespace.action" 格式,如 "llm.chat"、"db.set"
|
||||
- 内置能力以 "internal." 开头,如 "internal.legacy.call_context_function"
|
||||
|
||||
Attributes:
|
||||
name: 能力名称,格式为 "namespace.action"
|
||||
description: 能力描述,用于文档和调试
|
||||
input_schema: 输入参数的 JSON Schema,用于验证
|
||||
output_schema: 输出结果的 JSON Schema,用于验证
|
||||
supports_stream: 是否支持流式响应
|
||||
cancelable: 是否支持取消
|
||||
"""
|
||||
|
||||
name: str
|
||||
description: str
|
||||
input_schema: dict[str, Any] | None = None
|
||||
|
||||
@@ -1,3 +1,37 @@
|
||||
"""旧版协议适配器模块。
|
||||
|
||||
提供旧版 JSON-RPC 协议与新版协议之间的双向转换。
|
||||
支持旧版插件与新版核心的互操作。
|
||||
|
||||
主要功能:
|
||||
- 将旧版 JSON-RPC 请求转换为新版 InvokeMessage
|
||||
- 将旧版 JSON-RPC 响应转换为新版 ResultMessage
|
||||
- 将旧版 handshake 转换为新版 InitializeMessage
|
||||
- 将新版消息转换回旧版格式(用于与旧版核心通信)
|
||||
|
||||
转换映射表:
|
||||
旧版 method -> 新版 capability
|
||||
------------------------------------------------
|
||||
handshake -> InitializeMessage
|
||||
call_handler -> handler.invoke
|
||||
call_context_function -> internal.legacy.call_context_function
|
||||
handler_stream_start -> EventMessage(phase="started")
|
||||
handler_stream_update -> EventMessage(phase="delta")
|
||||
handler_stream_end -> EventMessage(phase="completed"/"failed")
|
||||
cancel -> CancelMessage
|
||||
|
||||
注意事项:
|
||||
- 旧版 handshake 的 metadata 信息可能丢失部分字段
|
||||
- 新版触发器的详细信息在转换时可能丢失
|
||||
- 使用 LEGACY_HANDSHAKE_METADATA_KEY 保留原始握手数据
|
||||
|
||||
TODO:
|
||||
- 添加旧版消息版本检测和兼容性警告
|
||||
- 添加消息转换日志记录,便于调试
|
||||
- 支持自定义转换规则扩展
|
||||
- 添加转换性能监控
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -17,10 +51,19 @@ from .messages import (
|
||||
)
|
||||
|
||||
LEGACY_JSONRPC_VERSION = "2.0"
|
||||
"""旧版 JSON-RPC 协议版本。"""
|
||||
|
||||
LEGACY_CONTEXT_CAPABILITY = "internal.legacy.call_context_function"
|
||||
"""旧版上下文函数调用的能力名称。"""
|
||||
|
||||
LEGACY_HANDSHAKE_METADATA_KEY = "legacy_handshake_payload"
|
||||
"""在 InitializeMessage.metadata 中存储原始握手数据的键。"""
|
||||
|
||||
LEGACY_PLUGIN_KEYS_METADATA_KEY = "legacy_plugin_keys"
|
||||
"""在 InitializeMessage.metadata 中存储原始插件键列表的键。"""
|
||||
|
||||
LEGACY_ADAPTER_MESSAGE_EVENT = 3
|
||||
"""默认的事件类型,用于无法识别的旧版处理器。"""
|
||||
|
||||
|
||||
class _LegacyMessageBase(BaseModel):
|
||||
@@ -28,12 +71,29 @@ class _LegacyMessageBase(BaseModel):
|
||||
|
||||
|
||||
class LegacyErrorData(_LegacyMessageBase):
|
||||
"""旧版 JSON-RPC 错误数据。
|
||||
|
||||
Attributes:
|
||||
code: 错误码,整数类型(旧版规范)
|
||||
message: 错误消息
|
||||
data: 附加错误数据
|
||||
"""
|
||||
|
||||
code: int = -32000
|
||||
message: str
|
||||
data: Any | None = None
|
||||
|
||||
|
||||
class LegacyRequest(_LegacyMessageBase):
|
||||
"""旧版 JSON-RPC 请求。
|
||||
|
||||
Attributes:
|
||||
jsonrpc: 协议版本,固定为 "2.0"
|
||||
id: 请求 ID,可选
|
||||
method: 方法名称
|
||||
params: 参数字典
|
||||
"""
|
||||
|
||||
jsonrpc: Literal["2.0"] = LEGACY_JSONRPC_VERSION
|
||||
id: str | None = None
|
||||
method: str
|
||||
@@ -46,20 +106,56 @@ class _LegacyResponse(_LegacyMessageBase):
|
||||
|
||||
|
||||
class LegacySuccessResponse(_LegacyResponse):
|
||||
"""旧版 JSON-RPC 成功响应。
|
||||
|
||||
Attributes:
|
||||
result: 返回结果
|
||||
"""
|
||||
|
||||
result: Any = Field(default_factory=dict)
|
||||
|
||||
|
||||
class LegacyErrorResponse(_LegacyResponse):
|
||||
"""旧版 JSON-RPC 错误响应。
|
||||
|
||||
Attributes:
|
||||
error: 错误数据
|
||||
"""
|
||||
|
||||
error: LegacyErrorData
|
||||
|
||||
|
||||
LegacyMessage = LegacyRequest | LegacySuccessResponse | LegacyErrorResponse
|
||||
"""旧版 JSON-RPC 消息联合类型。"""
|
||||
|
||||
LegacyToV4Message = (
|
||||
InitializeMessage | InvokeMessage | ResultMessage | EventMessage | CancelMessage
|
||||
)
|
||||
"""旧版消息转换后的新版消息类型。"""
|
||||
|
||||
|
||||
class LegacyAdapter:
|
||||
"""旧版协议适配器,提供新旧协议之间的双向转换。
|
||||
|
||||
使用场景:
|
||||
1. 旧版插件连接新版核心:将旧版 JSON-RPC 转换为新版协议
|
||||
2. 新版插件连接旧版核心:将新版协议转换为旧版 JSON-RPC
|
||||
3. 测试和迁移:验证协议转换的正确性
|
||||
|
||||
转换规则:
|
||||
- handshake <-> InitializeMessage
|
||||
- call_handler <-> InvokeMessage(capability="handler.invoke")
|
||||
- call_context_function <-> InvokeMessage(capability="internal.legacy...")
|
||||
- handler_stream_* <-> EventMessage
|
||||
- cancel <-> CancelMessage
|
||||
|
||||
Attributes:
|
||||
protocol_version: 新版协议版本号
|
||||
legacy_peer_name: 默认的对等节点名称
|
||||
legacy_peer_role: 默认的对等节点角色
|
||||
legacy_peer_version: 默认的对等节点版本
|
||||
"""
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
*,
|
||||
|
||||
@@ -1,3 +1,49 @@
|
||||
"""协议消息定义模块。
|
||||
|
||||
定义 AstrBot SDK 的核心消息类型,所有消息均继承自 Pydantic BaseModel。
|
||||
|
||||
消息类型概览:
|
||||
InitializeMessage: 握手初始化消息,包含 Peer 信息和处理器列表
|
||||
ResultMessage: 调用结果消息,包含成功/失败状态和输出数据
|
||||
InvokeMessage: 能力调用消息,指定目标能力和输入参数
|
||||
EventMessage: 流式事件消息,用于流式调用的状态通知
|
||||
CancelMessage: 取消消息,用于取消正在进行的调用
|
||||
|
||||
消息生命周期:
|
||||
握手阶段:
|
||||
Plugin -> Core: InitializeMessage (注册处理器)
|
||||
Core -> Plugin: ResultMessage (确认或拒绝)
|
||||
|
||||
调用阶段:
|
||||
Plugin -> Core: InvokeMessage (调用能力)
|
||||
Core -> Plugin: ResultMessage (返回结果)
|
||||
或者 (流式):
|
||||
Core -> Plugin: EventMessage (started -> delta* -> completed/failed)
|
||||
|
||||
取消阶段:
|
||||
Plugin -> Core: CancelMessage (取消调用)
|
||||
|
||||
与旧版对比:
|
||||
旧版 JSON-RPC:
|
||||
- 使用 method 字段区分操作类型
|
||||
- 使用 jsonrpc: "2.0" 标识协议版本
|
||||
- 错误码为整数 (如 -32000)
|
||||
- 无专门的取消消息类型
|
||||
|
||||
新版协议:
|
||||
- 使用 type 字段区分消息类型
|
||||
- 使用 protocol_version 字段标识版本
|
||||
- 错误码为字符串 (如 "internal_error")
|
||||
- 有专门的 CancelMessage 取消消息
|
||||
|
||||
TODO:
|
||||
- 添加消息过期时间 (expires_at) 支持
|
||||
- 添加消息优先级 (priority) 支持
|
||||
- 添加消息重试计数 (retry_count) 支持
|
||||
- ErrorPayload 缺少 stack_trace 字段(调试用)
|
||||
- InitializeMessage 缺少 authentication 认证字段
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
@@ -13,6 +59,19 @@ class _MessageBase(BaseModel):
|
||||
|
||||
|
||||
class ErrorPayload(_MessageBase):
|
||||
"""错误载荷,用于 ResultMessage 和 EventMessage 中传递错误信息。
|
||||
|
||||
与旧版 JSON-RPC 错误对比:
|
||||
旧版: code 为整数,如 -32000
|
||||
新版: code 为字符串,如 "internal_error"
|
||||
|
||||
Attributes:
|
||||
code: 错误码,字符串类型,便于语义化错误分类
|
||||
message: 错误消息,人类可读的错误描述
|
||||
hint: 错误提示,可选的解决方案或建议
|
||||
retryable: 是否可重试,标识该错误是否可通过重试解决
|
||||
"""
|
||||
|
||||
code: str
|
||||
message: str
|
||||
hint: str = ""
|
||||
@@ -20,12 +79,55 @@ class ErrorPayload(_MessageBase):
|
||||
|
||||
|
||||
class PeerInfo(_MessageBase):
|
||||
"""对等节点信息,标识消息发送方的身份。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 通过 handshake params 中的 plugin_name 隐式传递
|
||||
新版: 显式的 PeerInfo 结构,支持 plugin 和 core 两种角色
|
||||
|
||||
Attributes:
|
||||
name: 节点名称,通常是插件 ID 或核心标识
|
||||
role: 节点角色,"plugin" 或 "core"
|
||||
version: 节点版本号,可选
|
||||
"""
|
||||
|
||||
name: str
|
||||
role: Literal["plugin", "core"]
|
||||
version: str | None = None
|
||||
|
||||
|
||||
class InitializeMessage(_MessageBase):
|
||||
"""初始化消息,用于建立连接时交换信息。
|
||||
|
||||
与旧版 JSON-RPC handshake 对比:
|
||||
旧版:
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "xxx",
|
||||
"method": "handshake",
|
||||
"params": {}
|
||||
}
|
||||
响应包含插件元信息和处理器列表
|
||||
|
||||
新版:
|
||||
{
|
||||
"type": "initialize",
|
||||
"id": "xxx",
|
||||
"protocol_version": "1.0",
|
||||
"peer": {"name": "...", "role": "plugin", "version": "..."},
|
||||
"handlers": [...],
|
||||
"metadata": {...}
|
||||
}
|
||||
|
||||
Attributes:
|
||||
type: 消息类型,固定为 "initialize"
|
||||
id: 消息 ID,用于关联响应
|
||||
protocol_version: 协议版本号
|
||||
peer: 发送方节点信息
|
||||
handlers: 注册的处理器描述符列表
|
||||
metadata: 扩展元数据,可存储插件配置等信息
|
||||
"""
|
||||
|
||||
type: Literal["initialize"] = "initialize"
|
||||
id: str
|
||||
protocol_version: str
|
||||
@@ -35,12 +137,46 @@ class InitializeMessage(_MessageBase):
|
||||
|
||||
|
||||
class InitializeOutput(_MessageBase):
|
||||
"""初始化输出,作为 InitializeMessage 的响应数据。
|
||||
|
||||
与旧版对比:
|
||||
旧版: handshake 响应中包含完整的插件信息
|
||||
新版: 仅返回对等方信息和能力列表,更简洁
|
||||
|
||||
Attributes:
|
||||
peer: 接收方(核心)节点信息
|
||||
capabilities: 核心提供的能力描述符列表
|
||||
metadata: 扩展元数据
|
||||
"""
|
||||
|
||||
peer: PeerInfo
|
||||
capabilities: list[CapabilityDescriptor] = Field(default_factory=list)
|
||||
metadata: dict[str, Any] = Field(default_factory=dict)
|
||||
|
||||
|
||||
class ResultMessage(_MessageBase):
|
||||
"""结果消息,用于返回能力调用的结果。
|
||||
|
||||
与旧版 JSON-RPC 响应对比:
|
||||
旧版成功响应:
|
||||
{"jsonrpc": "2.0", "id": "xxx", "result": {...}}
|
||||
旧版错误响应:
|
||||
{"jsonrpc": "2.0", "id": "xxx", "error": {"code": -32000, "message": "..."}}
|
||||
|
||||
新版成功结果:
|
||||
{"type": "result", "id": "xxx", "success": true, "output": {...}}
|
||||
新版失败结果:
|
||||
{"type": "result", "id": "xxx", "success": false, "error": {...}}
|
||||
|
||||
Attributes:
|
||||
type: 消息类型,固定为 "result"
|
||||
id: 关联的请求 ID
|
||||
kind: 结果类型,可选,如 "initialize_result" 标识初始化结果
|
||||
success: 是否成功
|
||||
output: 成功时的输出数据
|
||||
error: 失败时的错误信息
|
||||
"""
|
||||
|
||||
type: Literal["result"] = "result"
|
||||
id: str
|
||||
kind: str | None = None
|
||||
@@ -50,6 +186,34 @@ class ResultMessage(_MessageBase):
|
||||
|
||||
|
||||
class InvokeMessage(_MessageBase):
|
||||
"""调用消息,用于请求执行远程能力。
|
||||
|
||||
与旧版 JSON-RPC 请求对比:
|
||||
旧版:
|
||||
{
|
||||
"jsonrpc": "2.0",
|
||||
"id": "xxx",
|
||||
"method": "call_handler",
|
||||
"params": {"handler_full_name": "...", "event": {...}}
|
||||
}
|
||||
|
||||
新版:
|
||||
{
|
||||
"type": "invoke",
|
||||
"id": "xxx",
|
||||
"capability": "handler.invoke",
|
||||
"input": {"handler_id": "...", "event": {...}},
|
||||
"stream": false
|
||||
}
|
||||
|
||||
Attributes:
|
||||
type: 消息类型,固定为 "invoke"
|
||||
id: 请求 ID,用于关联响应
|
||||
capability: 目标能力名称,格式为 "namespace.action"
|
||||
input: 调用输入参数
|
||||
stream: 是否期望流式响应,若为 True 将收到 EventMessage 序列
|
||||
"""
|
||||
|
||||
type: Literal["invoke"] = "invoke"
|
||||
id: str
|
||||
capability: str
|
||||
@@ -58,6 +222,32 @@ class InvokeMessage(_MessageBase):
|
||||
|
||||
|
||||
class EventMessage(_MessageBase):
|
||||
"""事件消息,用于流式调用的状态通知。
|
||||
|
||||
流式调用生命周期:
|
||||
1. started: 调用开始,所有字段为空
|
||||
2. delta: 数据增量更新,包含 data 字段
|
||||
3. completed: 调用完成,包含 output 字段
|
||||
4. failed: 调用失败,包含 error 字段
|
||||
|
||||
与旧版 JSON-RPC 通知对比:
|
||||
旧版使用独立的 method 区分:
|
||||
- handler_stream_start
|
||||
- handler_stream_update
|
||||
- handler_stream_end
|
||||
|
||||
新版使用统一的 EventMessage,通过 phase 字段区分:
|
||||
{"type": "event", "id": "xxx", "phase": "delta", "data": {...}}
|
||||
|
||||
Attributes:
|
||||
type: 消息类型,固定为 "event"
|
||||
id: 关联的请求 ID
|
||||
phase: 事件阶段,started/delta/completed/failed
|
||||
data: 增量数据,仅 delta 阶段有效
|
||||
output: 最终输出,仅 completed 阶段有效
|
||||
error: 错误信息,仅 failed 阶段有效
|
||||
"""
|
||||
|
||||
type: Literal["event"] = "event"
|
||||
id: str
|
||||
phase: Literal["started", "delta", "completed", "failed"]
|
||||
@@ -97,6 +287,18 @@ class EventMessage(_MessageBase):
|
||||
|
||||
|
||||
class CancelMessage(_MessageBase):
|
||||
"""取消消息,用于取消正在进行的调用。
|
||||
|
||||
与旧版对比:
|
||||
旧版: 使用 {"jsonrpc": "2.0", "method": "cancel", "params": {"reason": "..."}}
|
||||
新版: 专门的 CancelMessage 类型,语义更明确
|
||||
|
||||
Attributes:
|
||||
type: 消息类型,固定为 "cancel"
|
||||
id: 要取消的请求 ID
|
||||
reason: 取消原因,默认为 "user_cancelled"
|
||||
"""
|
||||
|
||||
type: Literal["cancel"] = "cancel"
|
||||
id: str
|
||||
reason: str = "user_cancelled"
|
||||
@@ -105,9 +307,29 @@ class CancelMessage(_MessageBase):
|
||||
ProtocolMessage = (
|
||||
InitializeMessage | ResultMessage | InvokeMessage | EventMessage | CancelMessage
|
||||
)
|
||||
"""协议消息联合类型,所有有效消息类型的联合。"""
|
||||
|
||||
|
||||
def parse_message(payload: str | bytes | dict[str, Any]) -> ProtocolMessage:
|
||||
"""解析协议消息。
|
||||
|
||||
从原始载荷(字符串、字节或字典)解析为对应的 ProtocolMessage 类型。
|
||||
根据 "type" 字段自动识别消息类型并验证。
|
||||
|
||||
Args:
|
||||
payload: 原始消息载荷,支持 JSON 字符串、字节或字典
|
||||
|
||||
Returns:
|
||||
解析后的协议消息对象
|
||||
|
||||
Raises:
|
||||
ValueError: 未知的消息类型
|
||||
|
||||
Example:
|
||||
>>> msg = parse_message('{"type": "invoke", "id": "1", "capability": "test"}')
|
||||
>>> isinstance(msg, InvokeMessage)
|
||||
True
|
||||
"""
|
||||
if isinstance(payload, bytes):
|
||||
payload = payload.decode("utf-8")
|
||||
if isinstance(payload, str):
|
||||
|
||||
Reference in New Issue
Block a user