- Add ConsensusSnapshot and ConsensusSlot classes for structured consensus state representation. - Introduce OnlineLanguageLearner for stateful online learning with experience replay and EWC regularization. - Create WorkspaceEvent and ActionEvent classes for serializable event types. - Develop InMemoryVectorMemoryStore for storing and querying workspace events. - Implement ActionPolicy to manage action selection and motor parameterization. - Establish a unified WorkspaceRuntime for managing the agent's lifecycle and interactions. - Enhance tests in test_smoke.py to cover new functionalities and ensure correctness.
129 lines
3.7 KiB
Python
129 lines
3.7 KiB
Python
"""
|
|
Serializable event types for the workspace-centered runtime.
|
|
|
|
These data packets are intentionally small and plain. They give local modules,
|
|
future worker processes, and external transports the same language for passing
|
|
workspace state around without sharing live Python objects.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from dataclasses import dataclass, field
|
|
import time
|
|
from typing import Any
|
|
|
|
import numpy as np
|
|
import torch
|
|
|
|
from .consensus import ConsensusSnapshot
|
|
|
|
|
|
def _workspace_vector(w: torch.Tensor | np.ndarray | list[float]) -> list[float]:
|
|
if isinstance(w, torch.Tensor):
|
|
data = w.detach().cpu()
|
|
if data.dim() > 1:
|
|
data = data[0]
|
|
return data.reshape(-1).tolist()
|
|
if isinstance(w, np.ndarray):
|
|
data = w
|
|
if data.ndim > 1:
|
|
data = data[0]
|
|
return data.reshape(-1).astype(float).tolist()
|
|
return [float(v) for v in w]
|
|
|
|
|
|
def _consensus_dict(consensus: ConsensusSnapshot | dict | None) -> dict | None:
|
|
if consensus is None:
|
|
return None
|
|
if isinstance(consensus, ConsensusSnapshot):
|
|
return consensus.to_dict()
|
|
return consensus
|
|
|
|
|
|
@dataclass
|
|
class WorkspaceEvent:
|
|
"""A transport-friendly snapshot of workspace state."""
|
|
|
|
step: int
|
|
modality: str
|
|
workspace: list[float]
|
|
consensus: dict | None = None
|
|
context: dict[str, Any] = field(default_factory=dict)
|
|
timestamp: float = field(default_factory=time.time)
|
|
kind: str = "workspace"
|
|
|
|
@classmethod
|
|
def from_tensor(
|
|
cls,
|
|
w: torch.Tensor | np.ndarray | list[float],
|
|
modality: str,
|
|
step: int = 0,
|
|
consensus: ConsensusSnapshot | dict | None = None,
|
|
context: dict | None = None,
|
|
) -> "WorkspaceEvent":
|
|
return cls(
|
|
step=step,
|
|
modality=modality,
|
|
workspace=_workspace_vector(w),
|
|
consensus=_consensus_dict(consensus),
|
|
context=context or {},
|
|
)
|
|
|
|
def workspace_array(self) -> np.ndarray:
|
|
return np.asarray(self.workspace, dtype=np.float32)
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"kind": self.kind,
|
|
"step": self.step,
|
|
"modality": self.modality,
|
|
"workspace": list(self.workspace),
|
|
"consensus": self.consensus,
|
|
"context": self.context,
|
|
"timestamp": self.timestamp,
|
|
}
|
|
|
|
|
|
@dataclass
|
|
class ActionEvent:
|
|
"""A transport-friendly action decision/result."""
|
|
|
|
step: int
|
|
action_idx: int
|
|
action_name: str
|
|
action_params: list[float]
|
|
executed: bool
|
|
risk: float = 0.0
|
|
context: dict[str, Any] = field(default_factory=dict)
|
|
timestamp: float = field(default_factory=time.time)
|
|
kind: str = "action"
|
|
|
|
@classmethod
|
|
def from_action_info(
|
|
cls,
|
|
action_info: dict,
|
|
step: int = 0,
|
|
context: dict | None = None,
|
|
) -> "ActionEvent":
|
|
return cls(
|
|
step=step,
|
|
action_idx=int(action_info.get("action_idx", 0)),
|
|
action_name=str(action_info.get("action_name", "observe")),
|
|
action_params=[float(v) for v in action_info.get("action_params", [])],
|
|
executed=bool(action_info.get("executed", False)),
|
|
risk=float(action_info.get("risk", 0.0)),
|
|
context=context or {},
|
|
)
|
|
|
|
def to_dict(self) -> dict:
|
|
return {
|
|
"kind": self.kind,
|
|
"step": self.step,
|
|
"action_idx": self.action_idx,
|
|
"action_name": self.action_name,
|
|
"action_params": list(self.action_params),
|
|
"executed": self.executed,
|
|
"risk": self.risk,
|
|
"context": self.context,
|
|
"timestamp": self.timestamp,
|
|
}
|