use serde::{Deserialize, Serialize};
use super::segment::{segment_transcript, SegmentFormat, SegmentKind, SegmentationPolicy};
use super::{fragment_id, CompilePolicy, CompileRequest};
use crate::error::MemoryError;
#[derive(Debug, Clone, Deserialize)]
pub struct TranscriptCompileInput {
pub query: String,
pub transcript: String,
pub token_budget: u64,
#[serde(default)]
pub project: Option<String>,
#[serde(default)]
pub target_model: Option<String>,
#[serde(default)]
pub policy: Option<CompilePolicy>,
#[serde(default)]
pub segmentation: Option<SegmentationPolicy>,
}
#[derive(Debug, Clone, Serialize)]
pub struct SegmentInfo {
pub index: usize,
pub turn: usize,
#[serde(skip_serializing_if = "Option::is_none")]
pub role: Option<String>,
pub kind: SegmentKind,
pub byte_start: usize,
pub byte_end: usize,
pub fragment_id: String,
}
#[derive(Debug, Clone, Serialize)]
pub struct SegmentationReport {
pub format_detected: SegmentFormat,
pub segments: Vec<SegmentInfo>,
pub merged_segments: usize,
}
pub fn build_transcript_compile_request(
input: TranscriptCompileInput,
) -> Result<(CompileRequest, SegmentationReport), MemoryError> {
if input.transcript.is_empty() {
return Err(MemoryError::SegmentationError(
"the transcript is empty — `transcript` must be non-empty text".to_owned(),
));
}
let outcome = segment_transcript(&input.transcript, &input.segmentation.unwrap_or_default())?;
let segments = outcome
.segments
.iter()
.enumerate()
.map(|(index, segment)| SegmentInfo {
index,
turn: segment.turn,
role: segment.role.clone(),
kind: segment.kind,
byte_start: segment.byte_start,
byte_end: segment.byte_end,
fragment_id: fragment_id(&segment.fragment.content).to_string(),
})
.collect();
let report = SegmentationReport {
format_detected: outcome.format_detected,
segments,
merged_segments: outcome.merged_segments,
};
let request = CompileRequest {
query: input.query,
fragments: outcome.segments.into_iter().map(|s| s.fragment).collect(),
project: input.project,
target_model: input.target_model,
token_budget: input.token_budget,
memory_scope: None,
policy: input.policy,
};
Ok((request, report))
}
#[cfg(test)]
#[path = "transcript_bridge_tests.rs"]
mod tests;