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

Method append_reasoning

atomic-agent/src/provenance/accumulator/append.rs:102–169  ·  view source on GitHub ↗

Append a reasoning/thinking node (chain-of-thought from the model). These are created from the reasoning blocks captured by the OpenCode plugin. Each block represents a distinct thinking step where the agent planned its approach, evaluated alternatives, or reasoned about the codebase. The node is classified as `Decision` (the existing kind for strategic choices). Edges link from the current goal

(
        &mut self,
        text: &str,
        duration_ms: Option<u64>,
        signature: Option<&str>,
        timestamp: i64,
    )

Source from the content-addressed store, hash-verified

100 ///
101 /// Returns the new node's ID.
102 pub fn append_reasoning(
103 &mut self,
104 text: &str,
105 duration_ms: Option<u64>,
106 signature: Option<&str>,
107 timestamp: i64,
108 ) -> String {
109 // Truncate for summary: first line or first 100 chars
110 let first_line = text.lines().next().unwrap_or(text);
111 let summary = if first_line.len() > 100 {
112 let truncated: String = first_line.chars().take(97).collect();
113 format!("{}...", truncated)
114 } else {
115 first_line.to_string()
116 };
117
118 let mut node = GraphNode::new(self.next_id(), NodeKind::Decision, timestamp, &summary);
119
120 if let Some(ms) = duration_ms {
121 node = node.with_duration_ms(ms);
122 }
123
124 // Build detail with the full reasoning text and signature
125 let mut detail = serde_json::json!({
126 "reasoning_text": text,
127 });
128 if let Some(ms) = duration_ms {
129 detail["reasoning_duration_ms"] = serde_json::Value::Number(ms.into());
130 }
131 if let Some(sig) = signature {
132 detail["anthropic_signature"] = serde_json::Value::String(sig.to_string());
133 }
134 detail["text_length"] = serde_json::Value::Number(text.len().into());
135 node.detail = Some(detail);
136
137 // Mark as classified so the Phase 3 consolidator doesn't touch it
138 node.classified = true;
139 node.confidence = Some(1.0);
140
141 let node_id = node.id.clone();
142
143 // Edge: goal --led_to-→ reasoning (if we have a current goal)
144 if let Some(ref goal) = self.current_goal {
145 self.edges.push(GraphEdge::new(
146 goal.clone(),
147 node_id.clone(),
148 EdgeKind::LedTo,
149 ));
150 self.stats.edge_count += 1;
151 }
152
153 // Also chain from previous node for temporal ordering
154 if let Some(ref prev) = self.last_node {
155 // Only add led_to if previous wasn't already the goal
156 if self.current_goal.as_ref() != Some(prev) {
157 self.edges.push(GraphEdge::new(
158 prev.clone(),
159 node_id.clone(),

Callers 1

Calls 9

next_idMethod · 0.80
with_duration_msMethod · 0.80
as_refMethod · 0.80
push_nodeMethod · 0.80
nextMethod · 0.45
linesMethod · 0.45
lenMethod · 0.45
cloneMethod · 0.45
pushMethod · 0.45

Tested by

no test coverage detected