Skip to main content

CHANGELOG.md

# Changelog

The format follows [Keep a Changelog](https://keepachangelog.com/) and the
project adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added
- Initial extraction as a standalone library.
- DAG builder with cycle detection (`Baton`, `Baton.DAG`).
- Node-backed state store (`workflow_nodes`) — no `oban_jobs.meta` mutation.
- Worker macros: `Baton.Worker`, `Baton.LLMWorker`.
- Dependency gating, completion-triggered rescheduling, retry idempotency.
- Multi-model fan-out + synthesis (`Baton.MultiModel`).
- `Baton.Plugin` (Oban plugin) for orphan rescue and failure telemetry.
- `Baton.Pricing` behaviour + reference implementation.
- Per-step stats and context-window capture (optional features).
- Versioned schema via `Baton.Migration`.
- Terminal `{:workflow_finished, _}` PubSub event (and
  `[:baton, :workflow, :finished]` telemetry) when a workflow's last step
  settles, with `:completed`/`:failed` outcome and the failed step names
  (`Baton.Completion`).
- `Baton.Plugin` backstops that notification for workflows that settle
  without a clean worker return (hard crash / Oban kill).
- Schema **v2**: `workflow_completions` table — an atomic claim guaranteeing the
  finished notification fires exactly once across the worker and plugin paths.
- Configurable LLM client for `Baton.Debug.call_llm/3`
  (`config :baton, llm_client: ...`).

- Opt-in data retention: `Baton.Plugin` can prune Baton's own tables
  (`workflow_nodes`, `workflow_step_stats`, `workflow_debug_logs`,
  `workflow_completions`) once their Oban job is pruned, with an optional shorter
  age cap for `workflow_debug_logs` (`prune: true`, `debug_log_max_age:`).
  See `Baton.Retention`.

### Changed
- `Baton.Migration.up/down` now default to the latest schema version when
  `:version` is omitted.
- `Baton.MultiModel.configure/2` model injection now happens inside
  `Baton.add/4`, so the documented `configure |> Baton.add` usage works.
  `Baton.MultiModel.add/4` is deprecated (now a passthrough).

### Removed
- `Baton.Stats.record_cache_hit` (dead code — was never called).

### Fixed
- `Baton.LLMWorker` no longer injects the Oban Pro-only `:kill_timeout`
  option, which made `use Baton.LLMWorker` fail to compile under Oban OSS.
  Replaced with a configurable `timeout/1` callback (`:timeout` option, default
  `:infinity`).
- PubSub broadcast failures no longer crash workers — broadcasting is now
  best-effort over telemetry (`Baton.Events`).
- `Baton.LLMWorker` stores the step result before recording stats and no
  longer raises on an unexpected `llm_usage` key, preventing a wasted/repeated
  LLM call on retry.