feat(observatory): admit canonical recorded replay
This commit is contained in:
@@ -6,6 +6,7 @@ from typing import Any, Literal
|
||||
|
||||
SessionStatus = Literal["ready", "interrupted", "failed"]
|
||||
SessionModality = Literal["point-cloud", "trajectory", "video"]
|
||||
LAB_REPLAY_CAPABILITY_SCHEMA = "missioncore.observation-lab-replay-capability/v1"
|
||||
|
||||
|
||||
class SessionStoreError(RuntimeError):
|
||||
@@ -28,6 +29,45 @@ class LayoutConflictError(SessionStoreError):
|
||||
"""A workspace layout revision changed since the caller loaded it."""
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class LabReplayCapability:
|
||||
"""Explicit, observation-only admission for a derived recorded replay."""
|
||||
|
||||
schema_version: Literal["missioncore.observation-lab-replay-capability/v1"]
|
||||
kind: Literal["canonical-recorded-rerun"]
|
||||
viewer_profile: Literal["recorded-session"]
|
||||
timeline: Literal["session_time"]
|
||||
activation: Literal["explicit"]
|
||||
commands_enabled: Literal[False]
|
||||
|
||||
def __post_init__(self) -> None:
|
||||
expected_text = (
|
||||
LAB_REPLAY_CAPABILITY_SCHEMA,
|
||||
"canonical-recorded-rerun",
|
||||
"recorded-session",
|
||||
"session_time",
|
||||
"explicit",
|
||||
)
|
||||
if (
|
||||
self.schema_version,
|
||||
self.kind,
|
||||
self.viewer_profile,
|
||||
self.timeline,
|
||||
self.activation,
|
||||
) != expected_text or self.commands_enabled is not False:
|
||||
raise ValueError("LAB replay capability is invalid")
|
||||
|
||||
def as_dict(self) -> dict[str, object]:
|
||||
return {
|
||||
"schema_version": self.schema_version,
|
||||
"kind": self.kind,
|
||||
"viewer_profile": self.viewer_profile,
|
||||
"timeline": self.timeline,
|
||||
"activation": self.activation,
|
||||
"commands_enabled": self.commands_enabled,
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class LabSessionBinding:
|
||||
"""Immutable provenance for one derived laboratory replay."""
|
||||
@@ -41,10 +81,15 @@ class LabSessionBinding:
|
||||
config_sha256: str | None
|
||||
run_created_at_utc: str
|
||||
published_at_utc: str
|
||||
replay_capability: LabReplayCapability | None
|
||||
provenance: dict[str, Any]
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
return {
|
||||
def as_dict(
|
||||
self,
|
||||
*,
|
||||
include_replay_capability: bool = False,
|
||||
) -> dict[str, Any]:
|
||||
document: dict[str, Any] = {
|
||||
"lab_id": self.lab_id,
|
||||
"source_session_id": self.source_session_id,
|
||||
"result_kind": self.result_kind,
|
||||
@@ -55,6 +100,11 @@ class LabSessionBinding:
|
||||
"published_at_utc": self.published_at_utc,
|
||||
"provenance": self.provenance,
|
||||
}
|
||||
if include_replay_capability:
|
||||
document["replay_capability"] = (
|
||||
None if self.replay_capability is None else self.replay_capability.as_dict()
|
||||
)
|
||||
return document
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
@@ -137,6 +187,8 @@ class SessionDetail:
|
||||
summary: SessionSummary
|
||||
sources: tuple[SessionSource, ...]
|
||||
artifacts: tuple[SessionArtifact, ...]
|
||||
plugin_id: str
|
||||
archive_id: str
|
||||
|
||||
def as_dict(self) -> dict[str, Any]:
|
||||
duration = self.summary.duration_seconds
|
||||
|
||||
Reference in New Issue
Block a user