Given extracted facts and existing memories, ask the LLM to decide whether each fact should be added, used to update an existing memory, delete an existing memory, or be ignored.
(
&self,
facts: &[String],
existing_memories: &[Memory],
)
| 71 | /// whether each fact should be added, used to update an existing memory, |
| 72 | /// delete an existing memory, or be ignored. |
| 73 | pub async fn decide_actions( |
| 74 | &self, |
| 75 | facts: &[String], |
| 76 | existing_memories: &[Memory], |
| 77 | ) -> GraphBitResult<Vec<MemoryDecision>> { |
| 78 | if facts.is_empty() { |
| 79 | return Ok(Vec::new()); |
| 80 | } |
| 81 | |
| 82 | let facts_list = facts |
| 83 | .iter() |
| 84 | .enumerate() |
| 85 | .map(|(i, f)| format!("{}. {f}", i + 1)) |
| 86 | .collect::<Vec<_>>() |
| 87 | .join("\n"); |
| 88 | |
| 89 | let memories_list = if existing_memories.is_empty() { |
| 90 | "No existing memories.".to_string() |
| 91 | } else { |
| 92 | existing_memories |
| 93 | .iter() |
| 94 | .map(|m| format!("ID: {} | Content: {}", m.id, m.content)) |
| 95 | .collect::<Vec<_>>() |
| 96 | .join("\n") |
| 97 | }; |
| 98 | |
| 99 | let system_prompt = concat!( |
| 100 | "You are a memory management assistant. Given new facts and existing memories, ", |
| 101 | "decide what action to take for each fact.\n\n", |
| 102 | "Actions:\n", |
| 103 | "- ADD: The fact is new information not captured by any existing memory.\n", |
| 104 | "- UPDATE: The fact refines or corrects an existing memory. Provide the target memory ID.\n", |
| 105 | "- DELETE: The fact contradicts or invalidates an existing memory. Provide the target memory ID.\n", |
| 106 | "- NOOP: The fact is already captured or is not worth storing.\n\n", |
| 107 | "Return a JSON array of objects with keys: \"fact\", \"action\", \"target_memory_id\" (null if ADD/NOOP).\n", |
| 108 | "Example: [{\"fact\":\"User lives in Berlin\",\"action\":\"UPDATE\",\"target_memory_id\":\"<uuid>\"}]", |
| 109 | ); |
| 110 | |
| 111 | let request = LlmRequest::with_messages(vec![ |
| 112 | LlmMessage::system(system_prompt), |
| 113 | LlmMessage::user(format!( |
| 114 | "New facts:\n{facts_list}\n\nExisting memories:\n{memories_list}" |
| 115 | )), |
| 116 | ]) |
| 117 | .with_max_tokens(self.max_tokens) |
| 118 | .with_temperature(self.temperature); |
| 119 | |
| 120 | let response = self.llm_provider.complete(request).await.map_err(|e| { |
| 121 | GraphBitError::memory(format!("Decision LLM call failed: {e}")) |
| 122 | })?; |
| 123 | |
| 124 | parse_decisions(&response.content) |
| 125 | } |
| 126 | } |
| 127 | |
| 128 | // --------------------------------------------------------------------------- |
no test coverage detected