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:362–429  ·  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

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