Build a `SessionEnvelope` for embedding in `HashedChange.metadata`.
(
options: &TurnRecordOptions<'_>,
recorded_files: &[String],
)
| 175 | |
| 176 | /// Build a `SessionEnvelope` for embedding in `HashedChange.metadata`. |
| 177 | pub(crate) fn build_turn_envelope( |
| 178 | options: &TurnRecordOptions<'_>, |
| 179 | recorded_files: &[String], |
| 180 | ) -> SessionEnvelope { |
| 181 | let prompt_summary = options |
| 182 | .prompt |
| 183 | .as_deref() |
| 184 | .filter(|p| is_meaningful_prompt(p)) |
| 185 | .map(|p| truncate_prompt(p, 200)); |
| 186 | |
| 187 | let prompt_hash = options |
| 188 | .prompt |
| 189 | .as_deref() |
| 190 | .filter(|p| is_meaningful_prompt(p)) |
| 191 | .map(|p| *blake3::hash(p.as_bytes()).as_bytes()); |
| 192 | |
| 193 | let files_in_turn: Vec<String> = recorded_files.to_vec(); |
| 194 | |
| 195 | let session_started_at = options.session.started_at.timestamp(); |
| 196 | let turn_ended_at = options.event.timestamp.timestamp(); |
| 197 | let turn_started_at = turn_ended_at - (options.turn_duration_ms as i64 / 1000); |
| 198 | |
| 199 | let mut builder = |
| 200 | SessionEnvelope::builder(&options.session.session_id, &options.session.agent_name) |
| 201 | .agent_display_name(&options.session.agent_display_name) |
| 202 | .turn_number(options.turn_number) |
| 203 | .session_started_at(session_started_at) |
| 204 | .turn_started_at(turn_started_at) |
| 205 | .turn_ended_at(turn_ended_at) |
| 206 | .turn_duration_ms(options.turn_duration_ms) |
| 207 | .files_in_turn(files_in_turn) |
| 208 | .files_in_session(options.session.files_touched_count()); |
| 209 | |
| 210 | if let Some(summary) = prompt_summary { |
| 211 | builder = builder.prompt_summary(summary); |
| 212 | } |
| 213 | if let Some(hash) = prompt_hash { |
| 214 | builder = builder.prompt_hash(hash); |
| 215 | } |
| 216 | |
| 217 | builder.build() |
| 218 | } |
| 219 | |
| 220 | // Step 6 Helper: Build Unhashed Turn Data |
| 221 |