parseCompactionResponse parses the LLM consolidation output back into facts.
(response string, originalFacts []*Fact)
| 228 | |
| 229 | // parseCompactionResponse parses the LLM consolidation output back into facts. |
| 230 | func (c *Compactor) parseCompactionResponse(response string, originalFacts []*Fact) []*Fact { |
| 231 | response = strings.TrimSpace(response) |
| 232 | lines := strings.Split(response, "\n") |
| 233 | |
| 234 | consolidated := make([]*Fact, 0, len(lines)) |
| 235 | for _, line := range lines { |
| 236 | line = strings.TrimSpace(line) |
| 237 | if line == "" || strings.HasPrefix(line, "#") || strings.HasPrefix(line, "---") { |
| 238 | continue |
| 239 | } |
| 240 | |
| 241 | // Remove bullet/numbering prefix |
| 242 | line = strings.TrimLeft(line, "0123456789.-) ") |
| 243 | line = strings.TrimPrefix(line, "* ") |
| 244 | line = strings.TrimPrefix(line, "- ") |
| 245 | line = strings.TrimSpace(line) |
| 246 | |
| 247 | if line == "" { |
| 248 | continue |
| 249 | } |
| 250 | |
| 251 | // Extract category from [category] prefix |
| 252 | category := "general" |
| 253 | if strings.HasPrefix(line, "[") { |
| 254 | end := strings.Index(line, "]") |
| 255 | if end > 0 { |
| 256 | category = strings.ToLower(strings.TrimSpace(line[1:end])) |
| 257 | line = strings.TrimSpace(line[end+1:]) |
| 258 | } |
| 259 | } |
| 260 | |
| 261 | if line == "" { |
| 262 | continue |
| 263 | } |
| 264 | |
| 265 | // Try to find matching original fact to preserve metadata |
| 266 | var matchedFact *Fact |
| 267 | for _, of := range originalFacts { |
| 268 | if strings.Contains(strings.ToLower(of.Content), strings.ToLower(line[:min(50, len(line))])) { |
| 269 | matchedFact = of |
| 270 | break |
| 271 | } |
| 272 | } |
| 273 | |
| 274 | fact := &Fact{ |
| 275 | Content: line, |
| 276 | Category: category, |
| 277 | CreatedAt: time.Now(), |
| 278 | LastAccessed: time.Now(), |
| 279 | AccessCount: 1, |
| 280 | Score: 1.0, |
| 281 | } |
| 282 | |
| 283 | if matchedFact != nil { |
| 284 | fact.CreatedAt = matchedFact.CreatedAt |
| 285 | fact.AccessCount = matchedFact.AccessCount |
| 286 | fact.Tags = matchedFact.Tags |
| 287 | // Trust metadata must survive consolidation: without this, every |