1
0
Fork 0
taleweave-ai/adventure/models/event.py

188 lines
3.7 KiB
Python
Raw Normal View History

2024-05-09 02:11:16 +00:00
from json import loads
from typing import Any, Callable, Dict, List, Literal
from uuid import uuid4
from pydantic import Field
2024-05-09 02:11:16 +00:00
from .base import dataclass
from .entity import Actor, Item, Room, WorldEntity
def uuid() -> str:
return uuid4().hex
2024-05-09 02:11:16 +00:00
class BaseEvent:
"""
A base event class.
"""
id: str
type: str
2024-05-09 02:11:16 +00:00
@dataclass
class GenerateEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
A new entity has been generated.
"""
id = Field(default_factory=uuid)
type = "generate"
2024-05-09 02:11:16 +00:00
name: str
entity: WorldEntity | None = None
@staticmethod
def from_name(name: str) -> "GenerateEvent":
return GenerateEvent(name=name)
@staticmethod
def from_entity(entity: WorldEntity) -> "GenerateEvent":
return GenerateEvent(name=entity.name, entity=entity)
@dataclass
class ActionEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
An actor has taken an action.
"""
id = Field(default_factory=uuid)
type = "action"
2024-05-09 02:11:16 +00:00
action: str
parameters: Dict[str, bool | float | int | str]
2024-05-09 02:11:16 +00:00
room: Room
actor: Actor
item: Item | None = None
@staticmethod
def from_json(json: str, room: Room, actor: Actor) -> "ActionEvent":
openai_json = loads(json)
return ActionEvent(
action=openai_json["function"],
parameters=openai_json["parameters"],
room=room,
actor=actor,
item=None,
)
@dataclass
class PromptEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
A prompt for an actor to take an action.
"""
id = Field(default_factory=uuid)
type = "prompt"
2024-05-09 02:11:16 +00:00
prompt: str
room: Room
actor: Actor
@dataclass
class ReplyEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
An actor has replied with text.
This is the non-JSON version of an ActionEvent.
"""
id = Field(default_factory=uuid)
type = "reply"
2024-05-09 02:11:16 +00:00
text: str
room: Room
actor: Actor
@staticmethod
def from_text(text: str, room: Room, actor: Actor) -> "ReplyEvent":
return ReplyEvent(text=text, room=room, actor=actor)
@dataclass
class ResultEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
A result of an action.
"""
id = Field(default_factory=uuid)
type = "result"
2024-05-09 02:11:16 +00:00
result: str
room: Room
actor: Actor
@dataclass
class StatusEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
A status broadcast event with text.
"""
id = Field(default_factory=uuid)
type = "status"
2024-05-09 02:11:16 +00:00
text: str
room: Room | None = None
actor: Actor | None = None
@dataclass
class SnapshotEvent(BaseEvent):
"""
A snapshot of the world state.
This one is slightly unusual, because the world has already been dumped to a JSON-compatible dictionary.
That is especially important for the memory, which is a dictionary of actor names to lists of messages.
"""
id = Field(default_factory=uuid)
type = "snapshot"
world: Dict[str, Any]
memory: Dict[str, List[Any]]
step: int
2024-05-09 02:11:16 +00:00
@dataclass
class PlayerEvent(BaseEvent):
2024-05-09 02:11:16 +00:00
"""
A player joining or leaving the game.
"""
id = Field(default_factory=uuid)
type = "player"
2024-05-09 02:11:16 +00:00
status: Literal["join", "leave"]
character: str
client: str
@dataclass
class PlayerListEvent(BaseEvent):
"""
A list of players in the game and the characters they are playing.
"""
id = Field(default_factory=uuid)
type = "players"
players: Dict[str, str]
@dataclass
class RenderEvent(BaseEvent):
"""
Images have been rendered.
"""
id = Field(default_factory=uuid)
type = "render"
paths: List[str]
source: "GameEvent"
2024-05-09 02:11:16 +00:00
# event types
WorldEvent = ActionEvent | PromptEvent | ReplyEvent | ResultEvent | StatusEvent
PlayerEventType = PlayerEvent | PlayerListEvent
GameEvent = GenerateEvent | PlayerEventType | RenderEvent | WorldEvent
2024-05-09 02:11:16 +00:00
# callback types
EventCallback = Callable[[GameEvent], None]