feat(plugins): isolate device integrations
This commit is contained in:
@@ -160,20 +160,44 @@ class WorkspaceLayout:
|
||||
}
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ReplayArtifact:
|
||||
"""One confined input artifact selected for plugin-owned preparation."""
|
||||
|
||||
artifact_id: str
|
||||
path: Path
|
||||
media_type: str
|
||||
file_byte_length: int
|
||||
replay_byte_length: int
|
||||
expected_sha256: str | None
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ReplayCommand:
|
||||
"""Internal-only replay command. ``source_path`` never enters an API DTO."""
|
||||
"""Internal replay request containing no vendor format or channel names."""
|
||||
|
||||
session_id: str
|
||||
source_path: Path
|
||||
plugin_id: str
|
||||
allowed_root: Path
|
||||
session_root: Path
|
||||
replay_byte_length: int
|
||||
metadata_byte_length: int
|
||||
expected_source_sha256: str | None
|
||||
primary_artifact_id: str
|
||||
artifacts: tuple[ReplayArtifact, ...]
|
||||
timeline_origin_epoch_ns: int
|
||||
timeline_origin_monotonic_ns: int
|
||||
speed: float
|
||||
loop: bool
|
||||
|
||||
@property
|
||||
def primary_artifact(self) -> ReplayArtifact:
|
||||
matches = tuple(
|
||||
artifact
|
||||
for artifact in self.artifacts
|
||||
if artifact.artifact_id == self.primary_artifact_id
|
||||
)
|
||||
if len(matches) != 1:
|
||||
raise SessionIntegrityError("replay command has no unique primary artifact")
|
||||
return matches[0]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class RecordedMediaArtifact:
|
||||
@@ -191,7 +215,19 @@ class RecordedMediaArtifact:
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class LegacySessionCandidate:
|
||||
class ObservationArtifactCandidate:
|
||||
artifact_id: str
|
||||
kind: str
|
||||
media_type: str
|
||||
locator: Path
|
||||
byte_length: int
|
||||
replay_byte_length: int
|
||||
sha256: str | None
|
||||
integrity_status: str
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
class ObservationSessionCandidate:
|
||||
session_id: str
|
||||
display_name: str
|
||||
status: SessionStatus
|
||||
@@ -203,13 +239,11 @@ class LegacySessionCandidate:
|
||||
total_bytes: int
|
||||
allowed_root: Path
|
||||
session_root: Path
|
||||
raw_path: Path
|
||||
raw_byte_length: int
|
||||
replay_raw_byte_length: int
|
||||
replay_metadata_byte_length: int
|
||||
raw_sha256: str | None
|
||||
raw_integrity_status: str
|
||||
media_sources: tuple[LegacyMediaSourceCandidate, ...]
|
||||
primary_replay_artifact_id: str | None
|
||||
timeline_origin_epoch_ns: int | None
|
||||
timeline_origin_monotonic_ns: int | None
|
||||
sources: tuple[SessionSource, ...]
|
||||
artifacts: tuple[ObservationArtifactCandidate, ...]
|
||||
|
||||
|
||||
@dataclass(frozen=True, slots=True)
|
||||
|
||||
Reference in New Issue
Block a user