MCPcopy Create free account
hub / github.com/atomicdotdev/atomic / build_unhashed_turn_data

Function build_unhashed_turn_data

atomic-agent/src/record/provenance.rs:227–292  ·  view source on GitHub ↗

Build the unhashed turn data (transcript + reasoning) from the agent's transcript file and the recorded change's FileOps. Returns `None` if the transcript is not available, empty, or unparseable. Reasoning generation failure is logged and skipped (non-fatal).

(
    options: &TurnRecordOptions<'_>,
    recorded_files: &[String],
    _outcome: &atomic_repository::record::RecordOutcome,
)

Source from the content-addressed store, hash-verified

225/// Returns `None` if the transcript is not available, empty, or unparseable.
226/// Reasoning generation failure is logged and skipped (non-fatal).
227pub(crate) fn build_unhashed_turn_data(
228 options: &TurnRecordOptions<'_>,
229 recorded_files: &[String],
230 _outcome: &atomic_repository::record::RecordOutcome,
231) -> Option<transcript::UnhashedTurnData> {
232 // Check if we have a transcript file
233 let transcript_path = options.session.transcript_path.as_ref()?;
234 if !transcript_path.exists() {
235 log::debug!(
236 "Transcript file not found at {} — skipping",
237 transcript_path.display(),
238 );
239 return None;
240 }
241
242 // Read raw transcript
243 let raw = match std::fs::read(transcript_path) {
244 Ok(data) => data,
245 Err(e) => {
246 log::warn!(
247 "Failed to read transcript at {}: {}",
248 transcript_path.display(),
249 e
250 );
251 return None;
252 }
253 };
254
255 if raw.is_empty() {
256 return None;
257 }
258
259 // Determine format from agent name
260 let format = if options.session.agent_name.contains("gemini") {
261 "json"
262 } else {
263 "jsonl"
264 };
265
266 // Condense into structured entries
267 let entries = transcript::condense_transcript(&raw, format);
268 if entries.is_empty() {
269 log::debug!("Condensed transcript is empty — skipping");
270 return None;
271 }
272
273 // Build the base unhashed data
274 let data = transcript::UnhashedTurnData::new(
275 &options.session.session_id,
276 options.turn_number,
277 format,
278 entries,
279 recorded_files,
280 );
281
282 // Reasoning generation is NOT done here — it's too slow for the hook
283 // hot path (calls Claude CLI, 30+ seconds) and potentially recursive
284 // when running inside a Claude Code hook.

Callers 1

record_turnFunction · 0.85

Calls 5

condense_transcriptFunction · 0.85
as_refMethod · 0.80
existsMethod · 0.45
is_emptyMethod · 0.45
containsMethod · 0.45

Tested by

no test coverage detected