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

Function build_unhashed_turn_data

atomic-agent/src/record/provenance.rs:228–293  ·  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

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