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

Function build_context_string

atomic-repository/src/ai/mod.rs:439–518  ·  view source on GitHub ↗

Build a compact text representation of KG nodes and edges for the LLM prompt. Groups nodes by kind and renders edges as relationship sentences. Hard cap at ~4000 characters to stay within context windows.

(nodes: &[KgNode], edges: &[KgEdge], query: &str)

Source from the content-addressed store, hash-verified

437/// Groups nodes by kind and renders edges as relationship sentences.
438/// Hard cap at ~4000 characters to stay within context windows.
439pub fn build_context_string(nodes: &[KgNode], edges: &[KgEdge], query: &str) -> String {
440 const MAX_CHARS: usize = 4000;
441 let mut buf = String::with_capacity(MAX_CHARS);
442 buf.push_str(&format!("Repository context for query: \"{}\"\n\n", query));
443
444 // Group by kind using a BTreeMap for deterministic output order
445 let mut groups: std::collections::BTreeMap<&str, Vec<&KgNode>> =
446 std::collections::BTreeMap::new();
447 for node in nodes {
448 groups.entry(node.kind.as_str()).or_default().push(node);
449 }
450
451 for (kind, group_nodes) in &groups {
452 buf.push_str(&format!("{}:\n", capitalize(kind)));
453 for node in group_nodes {
454 buf.push_str(&format!("- {}", node.label));
455 if let Some(ref summary) = node.summary {
456 buf.push_str(&format!(": {}", summary));
457 }
458 // Render metadata for change nodes (timestamp, author, sequence)
459 if node.kind == "change" {
460 if let Some(ref meta) = node.metadata {
461 let mut details = Vec::new();
462 if let Some(ts) = meta.get("timestamp").and_then(|v| v.as_str()) {
463 details.push(format!("date: {}", ts));
464 }
465 if let Some(seq) = meta.get("sequence").and_then(|v| v.as_u64()) {
466 details.push(format!("#{}", seq));
467 }
468 if !details.is_empty() {
469 buf.push_str(&format!(" ({})", details.join(", ")));
470 }
471 }
472 }
473 // Render metadata for entity nodes (kind, file, line range)
474 if node.kind == "entity" {
475 if let Some(ref meta) = node.metadata {
476 let mut details = Vec::new();
477 if let Some(k) = meta.get("kind").and_then(|v| v.as_str()) {
478 details.push(k.to_string());
479 }
480 if let Some(f) = meta.get("file").and_then(|v| v.as_str()) {
481 if let Some(line) = meta.get("line").and_then(|v| v.as_u64()) {
482 details.push(format!("{}:{}", f, line));
483 } else {
484 details.push(f.to_string());
485 }
486 }
487 if !details.is_empty() {
488 buf.push_str(&format!(" [{}]", details.join(", ")));
489 }
490 }
491 }
492 buf.push('\n');
493 if buf.len() >= MAX_CHARS {
494 break;
495 }
496 }

Calls 7

as_u64Method · 0.80
truncateMethod · 0.80
getMethod · 0.65
pushMethod · 0.45
as_strMethod · 0.45
is_emptyMethod · 0.45
lenMethod · 0.45