///|
pub(all) struct RobotGaitAlignmentDirectoryImportRequest {
root : String
source_dir : String
alignment_id : @robot_data.RobotGaitAlignmentId
episode_id : @robot_data.RobotEpisodeId
clip_id : @robot_data.RobotGaitClipId
annotation_id : @robot_data.RobotGaitAnnotationId
robot_id : @robot_data.RobotId
model_id : @robot_data.RobotModelId
imported_at_ms : Int64
source_label : String
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct ImportedRobotGaitAlignmentPayload {
source_path : String
relative_path : String
payload_path : String
alignment : @robot_data.RobotGaitAlignmentPayloadRef
} derive(Debug, Eq, ToJson, FromJson)
///|
pub(all) struct RobotGaitAlignmentDirectoryImportResult {
root : String
source_dir : String
alignment_id : @robot_data.RobotGaitAlignmentId
episode_id : @robot_data.RobotEpisodeId
clip_id : @robot_data.RobotGaitClipId
annotation_id : @robot_data.RobotGaitAnnotationId
robot_id : @robot_data.RobotId
model_id : @robot_data.RobotModelId
payload_count : Int
gait_alignment : @robot_data.RobotGaitAlignmentManifest
payloads : Array[ImportedRobotGaitAlignmentPayload]
materialization : RobotCatalogMaterialization
} derive(Debug, Eq, ToJson, FromJson)
///|
pub fn robot_gait_alignment_directory_import_request(
root : String,
source_dir : String,
alignment_id : @robot_data.RobotGaitAlignmentId,
episode_id : @robot_data.RobotEpisodeId,
clip_id : @robot_data.RobotGaitClipId,
annotation_id : @robot_data.RobotGaitAnnotationId,
robot_id : @robot_data.RobotId,
model_id : @robot_data.RobotModelId,
imported_at_ms : Int64,
source_label? : String = "Robot gait alignment directory import",
) -> RobotGaitAlignmentDirectoryImportRequest {
{
root,
source_dir,
alignment_id,
episode_id,
clip_id,
annotation_id,
robot_id,
model_id,
imported_at_ms,
source_label,
}
}
///|
fn gait_alignment_source_files(
source_dir : String,
) -> Result[Array[(String, String)], @data_store.DataStoreIssue] {
let names = match read_sorted_names(source_dir) {
Ok(value) => value
Err(error) => return Err(error)
}
let files : Array[(String, String)] = []
for name in names {
if !@data_core.data_relative_path_is_safe(name) {
return Err(
import_issue(
"unsafe-robot-gait-alignment-path", name, "robot gait alignment source contains an unsafe relative path",
),
)
}
let path = join(source_dir, name)
if !is_directory(path) {
files.push((path, name))
}
}
Ok(files)
}
///|
fn gait_alignment_content_type(relative_path : String) -> String {
if relative_path.has_suffix(".json") {
"application/json"
} else if relative_path.has_suffix(".csv") {
"text/csv"
} else {
"text/plain"
}
}
///|
fn gait_alignment_role(relative_path : String) -> String {
let mut value = relative_path
if value.has_suffix(".json") {
value = value[0:value.length() - 5].to_owned()
} else if value.has_suffix(".csv") {
value = value[0:value.length() - 4].to_owned()
} else if value.has_suffix(".txt") {
value = value[0:value.length() - 4].to_owned()
}
value
}
///|
fn alignment_line_count(body : String) -> Int {
if body.length() == 0 {
0
} else {
let mut count = 1
for char in body {
if char == '\n' {
count += 1
}
}
count
}
}
///|
fn gait_alignment_payload_data_ref(
alignment_id : @robot_data.RobotGaitAlignmentId,
relative_path : String,
body : String,
) -> @data_core.DataRef {
let payload_path = "payloads/robot_data/gait_alignments/\{alignment_id}/\{relative_path}"
@data_core.data_ref(
"robot-gait-alignment-\{safe_ref_segment(alignment_id)}-\{safe_ref_segment(relative_path)}",
"robot-gait-alignment",
@data_core.data_uri(payload_path),
content_type=gait_alignment_content_type(relative_path),
byte_count=body.length().to_int64(),
checksum=text_sum(body),
)
}
///|
pub fn import_robot_gait_alignment_directory(
request : RobotGaitAlignmentDirectoryImportRequest,
) -> Result[RobotGaitAlignmentDirectoryImportResult, @data_store.DataStoreIssue] {
match
validate_episode_import_id(request.alignment_id, "robot-gait-alignment-id") {
Ok(_) => ()
Err(error) => return Err(error)
}
match validate_episode_import_id(request.episode_id, "robot-episode-id") {
Ok(_) => ()
Err(error) => return Err(error)
}
match validate_episode_import_id(request.clip_id, "robot-gait-clip-id") {
Ok(_) => ()
Err(error) => return Err(error)
}
match
validate_episode_import_id(
request.annotation_id,
"robot-gait-annotation-id",
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let model_dossier = match
robot_model_catalog_dossier_from_root(request.root, request.model_id) {
Ok(value) => value
Err(error) => return Err(error)
}
let model = match model_ref_from_dossier(model_dossier, request.robot_id) {
Ok(value) => value
Err(error) => return Err(error)
}
match
robot_episode_catalog_dossier_from_root(request.root, request.episode_id) {
Ok(_) => ()
Err(error) => return Err(error)
}
match
robot_gait_clip_catalog_dossier_from_root(request.root, request.clip_id) {
Ok(_) => ()
Err(error) => return Err(error)
}
match
robot_gait_annotation_catalog_dossier_from_root(
request.root,
request.annotation_id,
) {
Ok(_) => ()
Err(error) => return Err(error)
}
let files = match gait_alignment_source_files(request.source_dir) {
Ok(value) => value
Err(error) => return Err(error)
}
if files.length() == 0 {
return Err(
import_issue(
"empty-robot-gait-alignment-directory",
request.source_dir,
"robot gait alignment source directory has no file payloads",
),
)
}
let payloads : Array[ImportedRobotGaitAlignmentPayload] = []
for index in 0..
return Err(
import_issue(
"read-robot-gait-alignment-payload", source_path, "failed to read robot gait alignment payload as text",
),
)
}
let data_ref = gait_alignment_payload_data_ref(
request.alignment_id,
relative_path,
body,
)
let payload_path = match stage_text_data_ref(request.root, data_ref, body) {
Ok(value) => value
Err(error) => return Err(error)
}
let payload = match payload_from_data_ref(data_ref) {
Ok(value) => value
Err(error) => return Err(error)
}
let alignment = @robot_data.robot_gait_alignment_payload_ref(
gait_alignment_role(relative_path),
alignment_line_count(body),
payload,
)
payloads.push({ source_path, relative_path, payload_path, alignment })
}
let gait_alignment = @robot_data.robot_gait_alignment_manifest(
request.alignment_id,
request.robot_id,
request.episode_id,
request.clip_id,
request.annotation_id,
"source-robot-gait-alignment-\{request.alignment_id}",
request.source_label,
request.source_dir,
@data_core.DataStatus::Verified,
request.imported_at_ms,
[model],
payloads.map(fn(payload) { payload.alignment }),
"Robot gait alignment for \{request.episode_id} and \{request.clip_id}",
)
match write_gait_alignments(request.root, [gait_alignment]) {
Ok(_) => ()
Err(error) => return Err(error)
}
match @data_store.rebuild_catalog(request.root, request.imported_at_ms) {
Ok(_) => ()
Err(error) => return Err(error)
}
let validation = match
@data_validate.validate_and_write_root(request.root, request.imported_at_ms) {
Ok(value) => value
Err(error) => return Err(error)
}
let catalog = match @data_store.read_catalog(request.root) {
Ok(value) => value
Err(error) => return Err(error)
}
Ok({
root: request.root,
source_dir: request.source_dir,
alignment_id: request.alignment_id,
episode_id: request.episode_id,
clip_id: request.clip_id,
annotation_id: request.annotation_id,
robot_id: request.robot_id,
model_id: request.model_id,
payload_count: payloads.length(),
gait_alignment,
payloads,
materialization: {
root: request.root,
catalog_path: validation.catalog_path,
validation_report_path: validation.report_path,
source_count: 1,
dataset_count: 1,
version_count: 1,
lineage_count: 1,
telemetry_stream_count: 0,
gait_clip_count: 0,
gait_annotation_count: 0,
gait_alignment_count: 1,
task_label_count: 0,
rollout_count: 0,
quality_report_count: 0,
catalog_entry_count: catalog.entries.length(),
validation_status: validation.status,
blocker_count: validation.blocker_count,
warning_count: validation.warning_count,
},
})
}