all repos — llm_aggregator @ 658b2cfd3cd0eca5835b921100e08569a426e199

A CLI tool to aggregate RSS feeds and summarise them with LLMs

CHANGELOG.md (view raw)

  1# Changelog
  2
  3All notable changes to this project will be documented in this file.
  4
  5The format is based on [Keep a
  6Changelog](https://keepachangelog.com/en/1.1.0/), and this project adheres to
  7[Semantic Versioning](https://semver.org/spec/v2.0.0.html).
  8
  9## [0.9.0] - 2026-04-23
 10
 11### Added
 12
 13- **Markdown rendering in TUI**: Implemented `charmbracelet/glamour` to
 14  render LLM summary output with proper markdown styling. Headers, bold,
 15  italic, code blocks, lists, and other markdown elements are now styled
 16  for better readability in the terminal.
 17- **Formalised infobar keybinds**: TUI keybinds are now defined as
 18  dedicated style variables at the top of the model for easier maintenance.
 19  Keybinds are bold while separators and action text are subtle but
 20  distinguishable.
 21- **Thinking indicator as separate element**: The `[đź’­ Thinking: ON/OFF]`
 22  toggle indicator is now on its own line above the keybinds, using a
 23  distinct style (magenta+bold when ON, subtle+italic when OFF).
 24- **Dynamic text wrapping on resize**: TUI summary text now re-wraps when
 25  the terminal window size or font changes, with proper markdown re-rendering.
 26
 27## [0.8.0] - 2026-04-23
 28
 29### Added
 30
 31- **Thinking tags toggle in TUI**: LLMs that output `<think>`/`</think>`
 32  thinking tags now have those sections automatically removed from the summary
 33  display by default. Users can press `t` to toggle the thinking section back
 34  on, displayed in gray at the head of the output with XML tags stripped for
 35  cleaner presentation. A status indicator shows whether thinking is currently
 36  visible.
 37
 38## [0.7.1] - 2026-04-22
 39
 40### Fixed
 41
 42- Environment variables were correctly overriding config file values, but CLI
 43  arguments without explicit flags were also overriding config file values
 44  unintentionally.
 45  - Root cause: `go-arg` was populating struct fields with default values
 46    from `default:` tags even when those CLI flags weren't provided
 47  - Fix: Removed `default:` tags from Args struct fields for LLM options
 48    (`model`, `base-url`, `api-key`, `max-tokens`, `temperature`);
 49    Viper's own default handling is sufficient
 50  - Fix: Changed Args struct fields from value types to pointer types
 51    (`*string`, `*int`, `*float64`) so that "not provided on CLI" can be
 52    distinguished from "provided but zero/empty"
 53  - Fix: Updated `BindCLIArgs()` and `isZero()` to properly handle pointer
 54    types and distinguish nil pointers from zero values
 55- `isZero()` with compound type switch cases: Compound type cases like `case
 56  *int, *int8, *int16, *int32, *int64` don't properly handle nil comparison when
 57  stored in an interface variable. Fixed by splitting into individual type cases.
 58- `isZero()` missing nil interface handling: When a nil pointer is stored
 59  in an `any` interface, `value != nil` returns `true` (the interface itself
 60  is not nil). Added early `if v == nil { return true }` check.
 61
 62## [0.7.0] - 2026-04-22
 63
 64### Added
 65
 66- **`--dry-run` option**: Validate configuration and preview what would happen
 67  without making any LLM API calls. Useful for validating feeds file and
 68  configuration, checking article counts and filtering results and anything
 69  else that can be done "offline".
 70- **Styled terminal output using `lipgloss`**: All CLI output now uses ANSI
 71  colour codes for better readability:
 72- **`$NO_COLOR` environment variable support**: Respects the ["no
 73color"](https://no-color.org/) standard. When `NO_COLOR` is set, all styling is
 74disabled and plain text is output instead.
 75
 76### Changed
 77
 78- API key validation now only occurs when not using `--dry-run` mode
 79
 80## [0.6.0] - 2026-04-22
 81
 82### Added
 83
 84- **Comprehensive unit test suite**, including CLI argument tests
 85  (`--feeds-file`, `--prompt`, `--api-key`, `--model`, `--base-url`),
 86  configuration tests, aggregator tests, output formatter tests, processor
 87  tests and defaults tests.
 88- **`--base-url` CLI option**: configure custom API endpoints for different LLM
 89  providers. Should support any OpenAI-compatible provider.
 90  - Environment variable: `LLM_AGGREGATOR_BASE_URL`
 91- `internal/defaults` package
 92- `docs/TESTING.md` which contains a comprehensive testing guide with test
 93  descriptions
 94
 95### Changed
 96
 97- **Configuration defaults**: All packages now use `defaults.Default*` constants
 98  - `internal/config`: Uses `defaults.Default*` for default values
 99  - `internal/runtime`: Uses `defaults.Default*` for runtime defaults
100  - `internal/llm`: Uses `defaults.Default*` for LLM client defaults
101
102### Fixed
103
104- `nil` pointer safety in aggregator
105  - Added nil checks for `progressCtx` across all log statements
106  - `FeedAggregator` now works correctly when progress context is nil
107  - Tests use `NewFeedAggregatorWithProgress` with explicit progress context
108
109## [0.5.0] - 2026-04-22
110
111### Added
112
113- **Accurate token counting with tiktoken**
114  - New `internal/tokeniser` package using OpenAI's tiktoken-go library
115  - BPE tokenisation for accurate token counting vs rough character estimation
116  - Encoding caching to avoid repeated initialisation overhead
117  - Model-aware encoding selection (cl100k_base, o200k_base, etc.)
118  - `CountTokens()` and `CountMessagesTokens()` functions
119  - Fallback to rough estimation when tiktoken initialisation fails
120- **Concurrent feed fetching**: Feeds are now fetched concurrently using
121  `golang.org/x/sync/errgroup`
122  - Semaphore limits concurrent requests to 10 to avoid server overload
123  - Mutex-protected shared state for thread-safe article collection
124  - Partial failures don't stop other feeds from being processed
125- **Scrollable summary in TUI**
126  - Bubble Tea viewport component for browsing long summaries
127  - Keyboard navigation: j/k or arrows (scroll), Space/B (page), g/G
128  (start/end)
129  - Mouse wheel scrolling support
130  - Scroll progress indicator showing position and total lines
131
132### Changed
133
134- **Streamlined configuration management**: Viper now uses global instance with
135automatic precedence handling. Simplified configuration flow: Parse → GetViper
136→ BindCLIArgs → ViperToRuntime
137- **TUI colour scheme**: All hex colour codes replaced with ANSI 256-colour
138  palette
139
140### Fixed
141
142- Viewport now properly handles scroll events via `Update()`. Summary content
143  pre-wrapped to viewport width before display
144- Fixed string literal colour names to use actual variables
145
146## [0.4.0] - 2026-04-21
147
148### Changed 
149
150- **TUI is now fully functional and production-ready**: Replaced the
151work-in-progress TUI implementation with a robust Bubble Tea command pattern:
152  - Runtime execution now uses native `tea.Cmd` instead of manual goroutine
153  orchestration.
154  - Added real-time progress updates via `progress.Progress` interface with
155  stage, substage, and article count messages.
156  - TUI displays a spinner, elapsed time, and final summary inline.
157  - Removed signal handling and channel synchronisation in favour of Bubble
158  Tea's built-in lifecycle.
159  - `TUIProgress` now only sends messages to an existing program, simplifying
160  integration.
161  - Both verbose mode (`SimpleLogger`) and TUI mode share the same
162  `progress.Progress` interface.
163
164## [0.3.0] - 2026-04-21
165
166### Added
167
168- **Configuration file support via TOML** (XDG-compliant and cross-platform)
169  - Load settings from `~/.config/llm_aggregator/config.toml`
170  - Supports all aggregation, API, and output options
171  - Example configuration file at `configs/config.example.toml`
172- **Environment variable support with `LLM_AGGREGATOR_` prefix**
173  - All configuration options can be set via environment variables
174  - Precedence order: CLI arguments > environment variables > config file >
175  built‑in defaults
176- New `internal/config` package with Viper integration
177  - `Load()` and `Save()` methods for configuration management
178  - `GetConfigPath()` for XDG‑compliant config file location
179  - `ConfigExists()` to check for existing configuration
180- Comprehensive unit tests for configuration loading, saving, and environment
181  variable precedence (`internal/config/config_test.go`)
182
183### Changed
184
185- **Environment variable renamed:** `DEEPSEEK_API_KEY` →
186  `LLM_AGGREGATOR_API_KEY`
187- **CLI help text** now reflects the new API key environment variable and
188  general configuration options
189- **Command‑line argument precedence** implemented in `cmd/llm_aggregator.go`
190via `applyConfiguration()`
191- Updated all help text, documentation, and code references
192- `README.md` completely revised with a new "Configuration" section
193
194### Removed
195
196- Global `QuietMode` and `VerboseMode` variables from
197`internal/config/config.go`. Replaced by runtime‑specific configuration in
198`runtime.Runtime` and CLI arguments
199- Hardcoded system prompt in `runtime.NewRuntime()`. Now left empty, allowing
200configuration or client default to be used
201- CLI flags now correctly override config file and environment variables
202
203## [0.2.0] - 2026-04-21
204
205### Changed
206
207- Moved all progress and status messages behind `-v/--verbose` flag
208- Default CLI mode is now silent except for final output and errors
209- Components (aggregator, processor, LLM client) use logger interface
210controlled by verbose flag
211
212## [0.1.0] - 2026-04-21
213
214### Added
215
216- Complete translation from Python prototype to Go implementation
217- RSS/Atom feed parsing using `gofeed` library
218- DeepSeek API integration via `openai-go` client, configured for `/chat/completions` endpoint
219- Content filtering and processing with keyword‑based include/exclude, date filtering, and sorting
220- Command‑line interface using `go‑arg` with automatic help and version flags
221- Multiple output formats: plain text, GitHub‑flavoured markdown, and JSON
222- Terminal user interface (TUI) built with `bubbletea` featuring:
223  - Animated progress bar with gradient colours (`#FF7CCB` to `#FDFF8C`)
224  - Live article counters (aggregated/processed)
225  - Elapsed time display
226  - Coloured status indicators using `lipgloss` styling
227  - Keyboard controls (q/Ctrl+C to quit)
228- Web content extraction fallback using `goquery` when feed descriptions are minimal
229- Configurable limits: articles per feed, maximum age, total articles
230- Token estimation and API usage logging
231- Environment variable support (`LLM_AGGREGATOR_API_KEY`) for authentication
232- Example feeds file with technology, programming, and free software sources
233
234### Changed
235
236- Program structure organised into standard Go layout: `cmd/`, `internal/`, `pkg/`
237- English spelling conventions maintained throughout (colour, initialise, summarise)
238- Error handling improved with specific messages for common API failures (invalid key, rate limits, etc.)
239- Progress reporting unified through a `ProgressContext` interface for both TUI and CLI modes
240
241### Fixed
242
243- Initial API endpoint mismatch (using `/responses` instead of `/chat/completions`)
244- Nil pointer dereferences when handling optional feed metadata (author, dates)
245- String repetition syntax errors in Go (replaced `"="*80` with `strings.Repeat`)
246- CLI help/version flag handling to show information without requiring other arguments
247- Type compatibility issues with `openai-go` v3 API (message parameters, token usage fields)