RunCompaction runs one compaction pass: list entries, group by period, for each group fetch content, optionally summarize, store result, delete originals.
(ctx context.Context, client KBCompactionClient, period string, summarize bool, apiURL, apiKey, model string)
| 131 | |
| 132 | // RunCompaction runs one compaction pass: list entries, group by period, for each group fetch content, optionally summarize, store result, delete originals. |
| 133 | func RunCompaction(ctx context.Context, client KBCompactionClient, period string, summarize bool, apiURL, apiKey, model string) error { |
| 134 | collection := client.Collection() |
| 135 | entries, err := client.ListEntries() |
| 136 | if err != nil { |
| 137 | return fmt.Errorf("list entries: %w", err) |
| 138 | } |
| 139 | groups := groupEntriesByPeriod(entries, period) |
| 140 | if len(groups) == 0 { |
| 141 | xlog.Debug("compaction: no groups to compact", "collection", collection, "period", period) |
| 142 | return nil |
| 143 | } |
| 144 | |
| 145 | var sum summarizer |
| 146 | if summarize && apiURL != "" && model != "" { |
| 147 | openAIClient := llm.NewClient(apiKey, apiURL, "120s") |
| 148 | sum = &openAISummarizer{client: openAIClient, model: model} |
| 149 | } |
| 150 | |
| 151 | for key, groupEntries := range groups { |
| 152 | if len(groupEntries) == 0 { |
| 153 | continue |
| 154 | } |
| 155 | var combined strings.Builder |
| 156 | for _, entry := range groupEntries { |
| 157 | entryContent, _, err := client.GetEntryContent(entry) |
| 158 | if err != nil { |
| 159 | xlog.Warn("compaction: get entry content failed", "entry", entry, "error", err) |
| 160 | continue |
| 161 | } |
| 162 | if entryContent != "" { |
| 163 | combined.WriteString(entryContent) |
| 164 | combined.WriteString("\n\n") |
| 165 | } |
| 166 | } |
| 167 | content := strings.TrimSpace(combined.String()) |
| 168 | if content == "" { |
| 169 | xlog.Debug("compaction: empty content for group", "key", key) |
| 170 | continue |
| 171 | } |
| 172 | |
| 173 | if sum != nil { |
| 174 | summary, err := sum.Summarize(ctx, content) |
| 175 | if err != nil { |
| 176 | xlog.Warn("compaction: summarize failed", "key", key, "error", err) |
| 177 | continue |
| 178 | } |
| 179 | content = summary |
| 180 | } |
| 181 | |
| 182 | // Store result as summary-<key>.txt |
| 183 | resultFilename := fmt.Sprintf("%s%s.txt", summaryPrefix, key) |
| 184 | tmpDir, err := os.MkdirTemp("", "localagi-compact") |
| 185 | if err != nil { |
| 186 | xlog.Warn("compaction: mkdir temp failed", "error", err) |
| 187 | continue |
| 188 | } |
| 189 | tmpPath := filepath.Join(tmpDir, resultFilename) |
| 190 | if err := os.WriteFile(tmpPath, []byte(content), 0644); err != nil { |
no test coverage detected
searching dependent graphs…