Parse the decision JSON from the LLM response.
(text: &str)
| 164 | |
| 165 | /// Parse the decision JSON from the LLM response. |
| 166 | fn parse_decisions(text: &str) -> GraphBitResult<Vec<MemoryDecision>> { |
| 167 | let trimmed = text.trim(); |
| 168 | |
| 169 | // Try to find and parse the JSON array. |
| 170 | let json_str = if let Some(start) = trimmed.find('[') { |
| 171 | if let Some(end) = trimmed.rfind(']') { |
| 172 | &trimmed[start..=end] |
| 173 | } else { |
| 174 | trimmed |
| 175 | } |
| 176 | } else { |
| 177 | trimmed |
| 178 | }; |
| 179 | |
| 180 | let raw: Vec<serde_json::Value> = serde_json::from_str(json_str).unwrap_or_default(); |
| 181 | |
| 182 | let decisions = raw |
| 183 | .into_iter() |
| 184 | .filter_map(|v| { |
| 185 | let fact = v.get("fact")?.as_str()?.to_string(); |
| 186 | let action_str = v.get("action")?.as_str()?; |
| 187 | let action = MemoryAction::from_str_lossy(action_str); |
| 188 | let target_memory_id = v |
| 189 | .get("target_memory_id") |
| 190 | .and_then(|t| t.as_str()) |
| 191 | .map(String::from); |
| 192 | |
| 193 | Some(MemoryDecision { |
| 194 | fact, |
| 195 | action, |
| 196 | target_memory_id, |
| 197 | }) |
| 198 | }) |
| 199 | .collect(); |
| 200 | |
| 201 | Ok(decisions) |
| 202 | } |
no test coverage detected