use kcode_k1_audio_classification_format::{
AudioClassificationEventV3, TranscriptionCompleteV1, TxId, encode_event,
};
use kcode_speaker_v3_analysis as current;
use kcode_speaker_v3_analysis_0_1 as previous;
use serde::Serialize;
#[derive(Serialize)]
struct PreviousTranscriptionCompleteV1 {
fragment_id: [u8; 12],
analysis: previous::ExecutedAnalysis,
}
fn current_analysis() -> current::ExecutedAnalysis {
let mut ogg = vec![0; 29];
ogg[..4].copy_from_slice(b"OggS");
ogg[26] = 1;
ogg[27] = 1;
current::ExecutedAnalysis {
envelope: current::AnalysisEnvelope {
audio: current::OggAudioMetadata::from_bytes(&ogg, 1_250, Some("sample.ogg".into()))
.expect("current Ogg metadata"),
analysis: current::StructuredAnalysis {
transcript: "Speaker 1: hello".into(),
speakers: vec![current::StructuredSpeaker {
speaker: current::LocalSpeakerLabel::new(1).expect("current speaker label"),
language: "English".into(),
features: current::FeatureVector24::default(),
features_usable_for_training: true,
}],
},
gemini: current::GeminiCohort {
model_id: "gemini".into(),
transcript_prompt_revision: "transcript-r1".into(),
feature_prompt_revisions: [
"feature-r1".into(),
"feature-r2".into(),
"feature-r3".into(),
],
feature_schema_revision: "schema-r1".into(),
},
structurer: current::StructurerProvenance {
model_id: "terra".into(),
prompt_revision: "structuring-r1".into(),
},
},
label_extractor: current::StructurerProvenance {
model_id: "terra".into(),
prompt_revision: "labels-r1".into(),
},
}
}
fn previous_analysis() -> previous::ExecutedAnalysis {
let mut ogg = vec![0; 29];
ogg[..4].copy_from_slice(b"OggS");
ogg[26] = 1;
ogg[27] = 1;
previous::ExecutedAnalysis {
envelope: previous::AnalysisEnvelope {
audio: previous::OggAudioMetadata::from_bytes(&ogg, 1_250, Some("sample.ogg".into()))
.expect("previous Ogg metadata"),
analysis: previous::StructuredAnalysis {
transcript: "Speaker 1: hello".into(),
speakers: vec![previous::StructuredSpeaker {
speaker: previous::LocalSpeakerLabel::new(1).expect("previous speaker label"),
language: "English".into(),
features: previous::FeatureVector24::default(),
features_usable_for_training: true,
}],
},
gemini: previous::GeminiCohort {
model_id: "gemini".into(),
transcript_prompt_revision: "transcript-r1".into(),
feature_prompt_revisions: [
"feature-r1".into(),
"feature-r2".into(),
"feature-r3".into(),
],
feature_schema_revision: "schema-r1".into(),
},
structurer: previous::StructurerProvenance {
model_id: "terra".into(),
prompt_revision: "structuring-r1".into(),
},
},
label_extractor: previous::StructurerProvenance {
model_id: "terra".into(),
prompt_revision: "labels-r1".into(),
},
}
}
#[test]
fn speaker_alignment_preserves_analysis_and_complete_event_bytes() {
let current = current_analysis();
let previous = previous_analysis();
assert_eq!(
postcard::to_allocvec(¤t).expect("serialize current analysis"),
postcard::to_allocvec(&previous).expect("serialize previous analysis")
);
let fragment_bytes = [7; 12];
let current_event = encode_event(&AudioClassificationEventV3::TranscriptionComplete(
TranscriptionCompleteV1 {
fragment_id: TxId::from_bytes(fragment_bytes),
analysis: current,
},
))
.expect("encode current event");
let mut previous_event = vec![4, 2];
previous_event.extend(
postcard::to_allocvec(&PreviousTranscriptionCompleteV1 {
fragment_id: fragment_bytes,
analysis: previous,
})
.expect("encode previous event body"),
);
assert_eq!(current_event, previous_event);
}