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

Function build_unhashed_turn_data

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

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