Build a `SessionEnvelope` for embedding in `HashedChange.metadata`.
(
options: &TurnRecordOptions<'_>,
recorded_files: &[String],
)
| 201 | |
| 202 | /// Build a `SessionEnvelope` for embedding in `HashedChange.metadata`. |
| 203 | pub(crate) fn build_turn_envelope( |
| 204 | options: &TurnRecordOptions<'_>, |
| 205 | recorded_files: &[String], |
| 206 | ) -> SessionEnvelope { |
| 207 | let prompt_summary = options |
| 208 | .prompt |
| 209 | .as_deref() |
| 210 | .filter(|p| is_meaningful_prompt(p)) |
| 211 | .map(|p| truncate_prompt(p, 200)); |
| 212 | |
| 213 | let prompt_hash = options |
| 214 | .prompt |
| 215 | .as_deref() |
| 216 | .filter(|p| is_meaningful_prompt(p)) |
| 217 | .map(|p| *blake3::hash(p.as_bytes()).as_bytes()); |
| 218 | |
| 219 | let files_in_turn: Vec<String> = recorded_files.to_vec(); |
| 220 | |
| 221 | let session_started_at = options.session.started_at.timestamp(); |
| 222 | let turn_ended_at = options.event.timestamp.timestamp(); |
| 223 | let turn_started_at = turn_ended_at - (options.turn_duration_ms as i64 / 1000); |
| 224 | |
| 225 | let mut builder = |
| 226 | SessionEnvelope::builder(&options.session.session_id, &options.session.agent_name) |
| 227 | .agent_display_name(&options.session.agent_display_name) |
| 228 | .turn_number(options.turn_number) |
| 229 | .session_started_at(session_started_at) |
| 230 | .turn_started_at(turn_started_at) |
| 231 | .turn_ended_at(turn_ended_at) |
| 232 | .turn_duration_ms(options.turn_duration_ms) |
| 233 | .files_in_turn(files_in_turn) |
| 234 | .files_in_session(options.session.files_touched_count()); |
| 235 | |
| 236 | if let Some(summary) = prompt_summary { |
| 237 | builder = builder.prompt_summary(summary); |
| 238 | } |
| 239 | if let Some(hash) = prompt_hash { |
| 240 | builder = builder.prompt_hash(hash); |
| 241 | } |
| 242 | |
| 243 | builder.build() |
| 244 | } |
| 245 | |
| 246 | // Step 6 Helper: Build Unhashed Turn Data |
| 247 |