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

Function save_learnings_to_context_file

atomic-agent/src/learnings.rs:364–431  ·  view source on GitHub ↗

Save learnings to the agent's context file. If the file doesn't exist, creates it with the learnings section. If the file exists but has no learnings section, appends the section. If the file exists with a learnings section, merges new learnings (deduplicating by finding text) and rewrites the section. # Arguments `repo_root` — Path to the repository root `agent_name` — Agent registry key (dete

(
    repo_root: &Path,
    agent_name: &str,
    learnings: &Learnings,
)

Source from the content-addressed store, hash-verified

362///
363/// Returns an error if the file cannot be read or written.
364pub fn save_learnings_to_context_file(
365 repo_root: &Path,
366 agent_name: &str,
367 learnings: &Learnings,
368) -> Result<SaveResult, std::io::Error> {
369 if learnings.is_empty() {
370 return Ok(SaveResult {
371 file_path: context_file_path(repo_root, agent_name),
372 added: 0,
373 skipped_duplicates: 0,
374 });
375 }
376
377 let file_path = context_file_path(repo_root, agent_name);
378
379 // Ensure parent directory exists (for .atomic/learnings.md)
380 if let Some(parent) = file_path.parent() {
381 std::fs::create_dir_all(parent)?;
382 }
383
384 // Read existing content (or empty string if file doesn't exist)
385 let existing_content = std::fs::read_to_string(&file_path).unwrap_or_default();
386
387 // Dedup against existing learnings
388 let original_count = context_file_learning_count(learnings);
389 let deduped = dedup_learnings(&existing_content, learnings);
390 let new_count = context_file_learning_count(&deduped);
391 let skipped = original_count - new_count;
392
393 if new_count == 0 {
394 return Ok(SaveResult {
395 file_path,
396 added: 0,
397 skipped_duplicates: skipped,
398 });
399 }
400
401 // Format the new learnings as individual items and merge by heading
402 let new_items = collect_new_items(&deduped);
403
404 // Build the updated file content
405 let updated_content = if existing_content.contains(SECTION_START) {
406 // Merge into existing headings (no duplicate ### Repo / ### Workflow)
407 merge_items_into_section(&existing_content, &new_items)
408 } else if existing_content.is_empty() {
409 let new_markdown = format_learnings_markdown(&deduped);
410 // New file — create with just the learnings section
411 build_new_section(&new_markdown)
412 } else {
413 // Existing file without a learnings section — append
414 let new_markdown = format_learnings_markdown(&deduped);
415 let mut content = existing_content.clone();
416 if !content.ends_with('\n') {
417 content.push('\n');
418 }
419 content.push('\n');
420 content.push_str(&build_new_section(&new_markdown));
421 content

Callers 10

runMethod · 0.85
test_save_new_fileFunction · 0.85
test_save_dedupFunction · 0.85
test_save_geminiFunction · 0.85

Calls 13

context_file_pathFunction · 0.85
dedup_learningsFunction · 0.85
collect_new_itemsFunction · 0.85
merge_items_into_sectionFunction · 0.85
build_new_sectionFunction · 0.85
writeFunction · 0.85
parentMethod · 0.80
is_emptyMethod · 0.45
containsMethod · 0.45
cloneMethod · 0.45