Download src/agentcade/protocol.py from left0ver/WatcherRobot-com.left0ver.agentcade: direct link, hf CLI and curl.
- Browser
- Download file 2.5 kB
-
https://huggingface.co/spaces/left0ver/WatcherRobot-com.left0ver.agentcade/resolve/main/src/agentcade/protocol.py
- Command line
-
hf download hf://spaces/left0ver/WatcherRobot-com.left0ver.agentcade/src/agentcade/protocol.py
-
curl -L -o protocol.py https://huggingface.co/spaces/left0ver/WatcherRobot-com.left0ver.agentcade/resolve/main/src/agentcade/protocol.py
2.5 kB
| from typing import Literal, TypeVar | |
| from a2a.helpers import new_data_part | |
| from a2a.types import Part | |
| from google.protobuf.json_format import MessageToDict | |
| from pydantic import BaseModel, ConfigDict, Field, model_validator | |
| PROTOCOL_VERSION = "desktop-game/5" | |
| class Model(BaseModel): | |
| model_config = ConfigDict(extra="forbid", str_strip_whitespace=True) | |
| class GameDescriptor(Model): | |
| id: str = Field(pattern=r"^[a-z][a-z0-9_]{0,63}$") | |
| name: str = Field(min_length=1) | |
| description: str = Field(min_length=1) | |
| aliases: list[str] = Field(default_factory=list) | |
| required_capabilities: list[str] = Field(default_factory=list) | |
| class Presentation(Model): | |
| text: str = Field(default="", max_length=500) | |
| paths: list[str] = Field(default_factory=list) | |
| expression: Literal["happy", "sorry"] | None = None | |
| gesture: Literal["nod", "shake_head"] | None = None | |
| clear: bool = False | |
| progress_seconds: int | None = Field(default=None, gt=0) | |
| class GameInput(Model): | |
| """主 Agent 发给游戏 Agent 的一条用户输入。""" | |
| model_config = ConfigDict(extra="forbid", str_strip_whitespace=False) | |
| protocol: Literal["desktop-game/5"] = PROTOCOL_VERSION | |
| kind: Literal["start", "message", "end"] | |
| text: str = Field(default="", description="用户原话,保持字词和标点") | |
| def validate_text(self): | |
| # 程序退出时发送的 end 没有用户原话。 | |
| if self.kind != "end" and not self.text.strip(): | |
| raise ValueError("开局和局内输入需要用户原话") | |
| return self | |
| class GameReply(Model): | |
| """游戏 Agent 回给主 Agent 的一条播报内容,一次请求至少回复一条。""" | |
| protocol: Literal["desktop-game/5"] = PROTOCOL_VERSION | |
| text: str = Field(min_length=1, max_length=500, description="主 Agent 原样播报的面向用户回复") | |
| session: Literal["active", "ended"] = Field( | |
| default="active", description="本局是否继续,只有一次请求的最后一条回复可以是 ended", | |
| ) | |
| Payload = TypeVar("Payload", GameInput, GameReply) | |
| def to_part(payload: GameInput | GameReply) -> Part: | |
| return new_data_part(payload.model_dump(mode="json")) | |
| def from_parts(model: type[Payload], parts) -> Payload: | |
| if len(parts) != 1 or not parts[0].HasField("data"): | |
| raise ValueError("游戏消息必须包含唯一一个结构化数据 Part") | |
| return model.model_validate(MessageToDict(parts[0].data)) | |