Current section

Files

Jump to
llm_composer CHANGELOG.md
Raw

CHANGELOG.md

# Changelog
All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [0.20.2] - 2026-07-08
### Added
- Added `:structured_output_strategy` option to the Bedrock provider (`:native` default, `:tool_use` opt-in). `:tool_use` requests `:response_schema` output by forcing the model to call a synthesized `structured_response` tool, working on Bedrock models without native structured-output support (Mistral, DeepSeek, older Qwen/Llama, etc.).
## [0.20.1] - 2026-07-01
### Added
- Added `:sse_middleware` option for streaming responses, allowing consumers to inject a custom SSE middleware instead of the default `Tesla.Middleware.SSE`.
## [0.20.0] - 2026-06-29
### Added
- Added `LlmComposer.Agent` — an automatic tool-calling loop that runs the full ask → execute → repeat cycle until the model returns a final answer. Supports sequential and parallel tool execution, configurable iteration limit, and per-tool error recovery.
- Added streaming support to `LlmComposer.Agent` (`stream_response: true`). Returns a lazy stream of `StreamChunk`s with `:text_delta`, `:tool_call` (one per executed tool, result included), and a terminal `:done` chunk carrying cumulative usage and the full `Agent.Result`. Supported providers: `:open_ai`, `:open_router`, `:open_ai_responses`, `:google`, `:bedrock`, `:ollama`.
- Added `:tool_call` chunk type to `LlmComposer.StreamChunk` — emitted by the streaming agent after each tool execution, making the stream self-contained without needing a telemetry handler.
- Added telemetry spans for `run_completion` and `providers_runner` calls, and enriched agent events with per-tool arguments, reasoning deltas, and a `:telemetry_metadata` option to scope handlers to a single run.
## [0.19.6] - 2026-06-16
### Changed
- Relaxed the declared `decimal` dependency constraint to support both 2.3.x and 3.x. `llm_composer`'s cost/pricing code was already compatible with Decimal 3.x, but downstream applications previously needed `override: true` to adopt the patched Decimal 3 line.
## [0.19.5] - 2026-06-01
### Added
- Bedrock HTTP receive timeout is now configurable via `config :llm_composer, :bedrock, receive_timeout: <ms>`. Falls back to the global `config :llm_composer, :timeout` and then to the previous hardcoded default of 30 000 ms. Applies to all Mint-based paths (streaming and non-streaming) as well as the shared `handle_stream_response` helpers used by Finch streaming.
## [0.19.4] - 2026-05-05
### Fixed
- Fixed Google cached token tracking: `cachedContentTokenCount` from `usageMetadata` is now extracted and populated in both `LlmResponse.cached_tokens` (non-streaming) and `StreamChunk.usage.cached_tokens` (streaming) instead of always being `nil`.
## [0.19.3] - 2026-04-30
### Fixed
- Fixed SSE streaming with `Tesla.Adapter.Mint`: the adapter now receives `body_as: :stream` instead of `response: :stream`, which is the correct option for Mint. Finch continues to use `response: :stream`. This means streaming no longer requires Finch — Mint (the default adapter) works out of the box.
## [0.19.2] - 2026-04-22
### Fixed
- Fixed reasoning (thinking) support to the Google stream chunk parser: chunks with `"thought": true` parts are now correctly split from text parts, populate the `StreamChunk.reasoning` field, and are emitted as `:reasoning_delta` instead of being mixed into `:text_delta`.
### Added
- Added `child_spec/1` to `LlmComposer.ProviderRouter.Simple` so it can be added to a supervision tree as a bare module (`children = [LlmComposer.ProviderRouter.Simple]`) without needing an explicit child spec map.
- Added HexDocs guides: Providers, Streaming, Cost Tracking, Function Calls, Provider Router, Custom Providers, Configuration Reference — splitting the previous monolithic README into focused, navigable documentation pages.
- Added `@doc` to `LlmComposer.Provider` behaviour callbacks and `@typedoc` to `Message`, `LlmResponse`, and `Settings` struct types for better in-editor and HexDocs documentation.
### Changed
- Slimmed `README.md` — it now serves as a discovery and getting-started document, with links to the full HexDocs guides for reference material.
## [0.19.1] - 2026-04-10
### Fixed
- Fixed Bedrock HTTP client non-streaming requests to use HTTP/1.1 (`protocols: [:http1]`) instead of HTTP/2 — Mint does not automatically manage HTTP/2 flow control (context window), which requires manual handling that is unnecessary for simple one-shot requests. Also corrected the `Mint.HTTP.request/5` error tuple to unwrap the connection from `{:error, _conn, error}` before returning.
## [0.19.0] - 2026-04-07
### Added
- Added automatic cost tracking for the Bedrock provider: token usage and costs are now populated in `LlmResponse.cost_info` when `track_costs: true` is set. Pricing is fetched automatically from models.dev (`amazon-bedrock` dataset) with a three-step lookup: exact model name, region prefix stripped (`eu.`, `us.`, `ap.`, `global.`), then date suffix stripped. Explicit `input_price_per_million` / `output_price_per_million` opts are also supported.
- Added streaming support for Amazon Bedrock via the `ConverseStream` API, with AWS Event Stream binary frame parsing.
- Added tool calls (function calling) support for Bedrock: request serialization with `toolConfig`, `toolUse` extraction from responses, `toolResult` formatting, and automatic merging of consecutive tool-result user turns as required by the Bedrock API.
- Added `LlmComposer.Providers.Bedrock.HttpClient` — a custom ExAws HTTP client that uses Mint by default for both streaming and regular requests, with optional Finch support when `config :llm_composer, :tesla_adapter, {Tesla.Adapter.Finch, name: MyFinch}` is set.
- Added `ProviderStreamChunk.Parser.Bedrock` to normalize Bedrock stream events (`text_delta`, `done`, `usage`) into the shared `StreamChunk` format.
- Added `response_schema` structured output support for Bedrock: pass a JSON schema map and it is automatically mapped to the Bedrock Converse API `outputConfig` format (schema is JSON-encoded as required by the API).
### Changed
- Bedrock now auto-injects `LlmComposer.Providers.Bedrock.HttpClient` as the ExAws HTTP client when `config :ex_aws, :http_client` is not explicitly set, removing the previous requirement to configure Hackney or Finch manually.
## [0.18.2] - 2026-04-01
### Changed
- Renamed `StreamChunk.tool_call` to `tool_calls` and updated its typespec from `map() | nil` to `list(LlmComposer.FunctionCall.t() | map()) | nil` — the field was already carrying a list in all parsers, so this aligns the struct definition with actual runtime values.
### Fixed
- Fixed Google streaming cost info to be built whenever usage data is present, not only on `:done` chunks — removes the unused `type` parameter from `build_cost_info/4`.
## [0.18.1] - 2026-04-01
### Added
- Added `:tool_call_delta` stream chunk type for Google provider: chunks containing `functionCall` parts are now correctly classified as `:tool_call_delta` with the `tool_call` field populated as a list of `%LlmComposer.FunctionCall{}` structs, instead of being silently emitted as empty `:text_delta` chunks.
- Added `reasoning_tokens` extraction from `thoughtsTokenCount` in Google streaming responses — the final `:done` chunk now populates `chunk.usage.reasoning_tokens` for Gemini thinking models.
- Added `reasoning_tokens` extraction from `thoughtsTokenCount` in Google non-streaming responses — `LlmResponse.reasoning_tokens` is now populated from `usageMetadata.thoughtsTokenCount`.
## [0.18.0] - 2026-03-26
### Added
- Added `function_calls` as a typed `[LlmComposer.FunctionCall.t()] | nil` field directly on `%LlmComposer.Message{}`, replacing the untyped `metadata[:tool_calls]` map access previously used in conversation history.
- Added `LlmResponse.function_calls/1` delegate function for convenient access to the function calls of the main response message.
### Changed
- Moved `function_calls` from `%LlmComposer.LlmResponse{}` struct field to `%LlmComposer.Message{}`, eliminating the duplication between `LlmResponse.function_calls` (initial response) and `Message.metadata[:tool_calls]` (conversation history). OpenAI, OpenRouter, and Google parsers now set `function_calls` directly on the assistant message.
- Updated `Providers.Utils` message mappers for OpenAI, OpenRouter, and Google to read `message.function_calls` instead of `message.metadata[:tool_calls]`.
## [0.17.1] - 2026-03-26
### Fixed
- Fixed Google provider parallel tool call message mapping to correctly merge consecutive `functionResponse` user turns into a single turn as required by the Google API.
## [0.17.0] - 2026-03-25
### Added
- Added `:reasoning_delta` stream chunk support for OpenAI, OpenAI Responses, and Ollama streams, including `reasoning` and `reasoning_details` payloads on normalized `%LlmComposer.StreamChunk{}` values.
- Added parsing of reasoning summary blocks from OpenAI Responses streaming events (`response.output_item.done` and `response.completed`).
- Added `reasoning_tokens`, `provider_model`, `cached_tokens`, and `response_id` fields to `%LlmComposer.LlmResponse{}` so consuming apps no longer need to dig into raw provider response structures.
- Added `cached_tokens` and `reasoning_tokens` to the `StreamChunk.usage()` type, populated on the final `:usage`/`:done` chunk for OpenAI, OpenAI Responses, OpenRouter, and Google streams.
- Added `cost_info` population on the final stream chunk (`:usage` or `:done`) for all providers — consumers can read `chunk.cost_info` directly instead of computing it after the stream.
- Added `cached_tokens` and `cache_read_price_per_million` fields to `%LlmComposer.CostInfo{}`.
- Added `cache_read_price_per_million` extraction from models.dev API responses when available, enabling automatic cache-read pricing for OpenAI models.
- Added `previous_response_id` forwarding in OpenAI Responses API requests via the `:previous_response_id` option.
### Fixed
- Fixed Google provider message mapping to preserve `thought_signature` and other fields from Gemini thinking models by reusing `parts` from the original response when available.
### Changed
- Updated OpenAI/OpenRouter response parsing to better handle streamed chunk lists, tuple-list payloads with string or atom keys, content arrays, and empty-choice errors.
- Updated Ollama response parsing so non-streaming responses map `message.thinking` into `reasoning`, and streaming responses preserve raw chunk lists for normalized stream parsing.
- Updated token and pricing extraction to support both map and keyword-style payloads when assembling cost information, using the actual response model for OpenAI/OpenAI Responses pricing.
- Updated pricing lookup so `:open_ai_responses` reuses OpenAI pricing data from models.dev, including fallback from dated snapshot model names to the base model entry.
- Updated cost calculation to bill cached prompt tokens with provider cache-read pricing when available, and fall back to standard input pricing when no separate cached-token price is exposed.
- Updated OpenAI Responses `normalize_usage` to preserve `input_tokens_details` so cached-token cost calculation receives the correct data downstream.
- Fixed compiler warnings introduced by Elixir 1.19: struct updates in `FunctionExecutor` and `LlmComposer` now include the required struct pattern match at the binding site.
- Moved `preferred_cli_env` from `def project` to the new `def cli` callback in `mix.exs`, removing the deprecation warning on Elixir 1.19+.
- Updated `credo` from 1.7.12 to 1.7.17 to fix a crash in `DuplicatedCode` check on Elixir 1.19.
## [0.16.2] - 2026-03-25
### Changed
- Adjusted `@spec` for `ProvidersRunner.run/3` to use `{:error, term()}` instead of `{:error, atom()}`, reflecting that errors are not always atoms.
## [0.16.1] - 2026-03-23
### Added
- Added `reasoning` and `reasoning_details` optional fields to `LlmComposer.Message` to capture reasoning tokens returned by reasoning models (e.g. via OpenRouter).
- OpenRouter provider now forwards `reasoning` and `reasoning_details` when serializing assistant messages, enabling multi-turn conversations that preserve reasoning context across requests.
### Changed
- Added `mix precommit` alias (compile + format check + credo + tests) for a single pre-commit verification command.
## [0.16.0] - 2026-02-23
### Added
- Added `LlmComposer.Providers.OpenAIResponses` provider to call OpenAI's `/responses` API, including support for `reasoning_effort` and structured outputs while keeping a normalized `LlmResponse` shape.
- Added `LlmComposer.StreamChunk` and provider-specific stream chunk parsing so streaming events are normalized into typed chunks (`:text_delta`, `:tool_call_delta`, `:done`, etc.).
- Added `LlmComposer.FunctionCallExtractors` to centralize provider-specific function call extraction logic.
### Changed
- Changed `LlmComposer.parse_stream_response` to be provider-aware (`parse_stream_response/2` and `parse_stream_response/3`) and return normalized `%LlmComposer.StreamChunk{}` values instead of raw decoded maps.
- Updated cost/token extraction to include `:open_ai_responses` provider responses.
- Updated OpenAI request handling to use shared timeout/request option helpers (including adapter `receive_timeout` support).
- Refactored provider response parsing into protocol-based adapters (`LlmComposer.ProviderResponse` and `LlmComposer.ProviderStreamChunk`) for clearer provider-specific normalization.
- Updated `README.md` with OpenAI Responses API and normalized streaming chunk documentation.
- Expanded `LlmComposer.Provider` moduledoc with a minimal implementation guide for creating custom providers.
- Updated ExDoc configuration to include `LICENSE` in docs extras.
- Updated dependency `ex_doc` from `0.31` to `0.34` and enabled `warn_if_outdated: true`.
## [0.15.0] - 2026-02-17
### Added
- Added configurable JSON engine for HTTP requests: new `:json_engine` config option allows specifying JSON encoder/decoder library (defaults to JSON, falls back to Jason).
### Changed
- Changed Google provider to keep `additionalProperties` in response schemas instead of removing them, allowing for more flexible schema definitions.
- Updated dependency `ex_aws` from 2.5 to 2.6.
- Updated dependency `tesla` from 1.14 to 1.16.
- Restructured configuration in `config/config.exs` with better provider organization.
## [0.14.2] - 2026-02-10
### Changed
- Changed `LlmResponse.new/3` to return an error tuple instead of raising an exception when encountering unhandled response formats from providers, for easier error handling/debugging.
## [0.14.1] - 2026-02-09
### Fixed
- Fixed `request_params` merging to use deep merge instead of shallow merge, allowing nested configurations (like `generationConfig` in Google provider) to be properly combined with provider defaults.
## [0.14.0] - 2026-02-04
### Added
- Configurable retry/backoff for provider requests: new settings allow configuring retry attempts and backoff behavior for provider calls (e.g. max attempts, base delay, backoff factor). This improves robustness when providers return transient errors.
## [0.13.1] - 2026-01-09
### Added
- Added ability to set custom HTTP request headers for OpenRouter provider.
- Updated README with documentation on configuring custom headers for OpenRouter.
## [0.13.0] - 2025-12-01
### Changed
- Replaced the previous auto function execution workflow with a manual process powered by `FunctionExecutor` and `FunctionCallHelpers`, and added README guidance for executing OpenAI/OpenRouter/Google function calls explicitly.
### Added
- `LlmComposer.FunctionExecutor` for explicit/manual execution of function calls returned by providers.
- `LlmComposer.FunctionCallHelpers` with helpers to build assistant messages and tool-result messages when handling function calls.
### Changed
- Replaced the previous auto function execution workflow with a manual process and updated the public APIs accordingly.
- `LlmComposer.LlmResponse` now exposes `function_calls` instead of the previous `actions` field and normalizes provider-specific function-call formats.
- `LlmComposer.Providers.Utils` message mapping and request/response formatting updated to support explicit `:tool_result` messages and provider-specific assistant formats (OpenAI/Google/OpenRouter).
- `LlmComposer.Helpers` was simplified/trimmed to remove automatic execution helpers in favor of the manual executor.
- `README.md` updated with a new "Function Calls" section demonstrating the manual workflow, API usage, and examples.
### Breaking Changes
- Removed the auto-execution helpers/tests and related documentation that assumed functions ran automatically.
- Settings struct keys `:auto_exec_functions` and `:functions` were removed; function descriptors are expected to be provided per-call or via provider options.
- Tests that relied on automatic function execution were removed (`test/llm_composer/function_calls_auto_execution_test.exs`).
## [0.12.3] - 2025-11-07
### Changed
- decimal dep mandatory
## [0.12.2] - 2025-11-06
### Changed
- Changed license from GPL-3.0 to MIT
- Updated documentation and improved code examples
## [0.12.0] - 2025-10-17
### Removed
- Removed support for deprecated `:provider` and `:provider_opts` settings keys. Use `:providers` list instead.
- Removed support for global `:api_key` setting in Settings struct. Specify `:api_key` per-provider in the `:providers` list.
- Removed backward compatibility handling for deprecated settings in `LlmComposer` and `ProvidersRunner`.
### Added
- Automatic cost tracking for OpenAI, Google, and OpenRouter providers:
- Fetches real-time pricing from provider APIs (models.dev for OpenAI/Google, OpenRouter API).
- `CostInfo` struct in responses with token usage and cost breakdowns.
- Support for automatic and manual pricing configuration.
- `Pricing` module for cost calculations.
- Supporting modules for OpenRouter pricing and tracking.
### Changed
- Enhanced `LlmResponse` to include cost information.
- Updated provider implementations (OpenAI, Google, OpenRouter) to support cost tracking.
- Updated README with examples for cost tracking.
- Refactored cost information retrieval and pricing module structure for improved maintainability.
- Updated AGENTS.md with current development guidelines.
## [0.11.2] - 2025-09-25
- Updated README a bit more docs and examples. Included in new release for hex docs too.
## [0.11.1] - 2025-09-23
- Added OpenRouter function-call support and provider message-mapping fixes; preserved assistant tool_calls during auto-executed functions.
## [0.11.0] - 2025-09-23
- **Implement multi-provider support with provider routing and failover:**
- Introduced a new `:providers` list in `LlmComposer.Settings` to replace deprecated `:provider` and `:provider_opts` keys.
- Added validation in `LlmComposer` to enforce/suggest exclusive use of `:providers` and warn about deprecated keys.
- Implemented `LlmComposer.ProvidersRunner` to handle provider execution, supporting multiple providers with fallback logic.
- Added `LlmComposer.ProviderRouter` behaviour for routing strategies on provider selection, failure handling, and blocking.
- Provided a simple default provider router `LlmComposer.ProviderRouter.Simple` with exponential backoff blocking on provider failures.
- Refactored `LlmComposer.run_completion/3` to delegate to `ProvidersRunner` for provider selection and execution.
- Optimized `LlmComposer.Cache.Ets` by switching `put` and `delete` calls to asynchronous casts, improving performance.
- Maintained backward compatibility with deprecated settings keys, issuing warnings and supporting legacy calls until version 0.12.0.
- Changed `response_format` key to `response_schema` for better structured output definition that works across multiple providers.
- Structured outputs now available for OpenAI provider as well.
- Default JSON module is JSON; falls back to Jason if JSON is not loaded.
## [0.10.0] - 2025-09-03
- **Add Google (Gemini) provider**: Full feature support including chat, functions, streaming, and structured outputs.
- **Add Vertex AI integration**: Same Google provider but can be used with it's Vertex API. Enterprise support with OAuth 2.0 authentication via Goth library.
## [0.9.0] - 2025-09-01
- Update elixir(1.18) and erlang(28).
## [0.8.0] - 2025-08-12
- **Add tracking costs for OpenRouter provider**: Introduced cost tracking functionality specifically for the OpenRouter provider to monitor API usage expenses.
## [0.7.0] - 2025-07-31
- **Add HttpClient module**: Introduced a new HttpClient module for improved HTTP handling.
- **Add streaming read capability**: Added the capability of streaming read for LLM providers completions.
- **Documentation and config updates**: Updates to README.md and configuration files.
## [0.6.0] - 2025-07-17
- **Refactor Models to Providers**: Renamed the "Models" module to "Providers" to better reflect the architecture and improve code organization.
- **Fix optional ex_aws dependency**: Fixed the ex_aws dependency to be truly optional by adding missing `Code.ensure_loaded` checks that were making the dependency mandatory.
## [0.5.5] - 2025-07-08
- **Fix typos**: Fixed various typos throughout the codebase.
## [0.5.4] - 2025-07-07
- **Add support for structured outputs in OpenRouter**: Added functionality to support structured outputs when using the OpenRouter model.
## [0.5.3] - 2025-06-30
- **Remove provider_routing from OpenRouter**: Removed the `provider_routing` functionality from the OpenRouter model, simplifying the model configuration and request building process.
## [0.5.2] - 2025-06-19
- **Making `ex_aws` dependency optional**: `ex_aws` is only required for the Bedrock provider. Making it optional so it is not included in case Bedrock is not used. Additionally, removing the `Logger.error()` in case of a model error, delegating this to the caller of the library.
## [0.5.1] - 2025-06-12
- **Adjust `Message.content` specs**: For Bedrock, the `content` field of the message has to be a list, allowing for messages with with multi-type content (image + text).
## [0.5.0] - 2025-06-12
- **Include Bedrock Support**: Included Bedrock support as provider only with `completion()`s support.
## [0.3.5] - 2024-12-18
- **Fix default api_key setting value**: The default value was en empty string. Now it is nil to be evaluated as false when getting the key from the map later.
## [0.3.4] - 2024-12-17
- **OpenAI API Keys**: Use an API key passed as a parameter when calling chat_completion — overriding the global API key defined in the config. The param is sent inside the settings.
## [0.3.3] - 2024-12-04
- **Timeouts**: Configurable OpenAI's timeout. Default set to 50 seconds.
## [0.3.2] - 2024-12-03
- **Timeouts**: Fix OpenAI-timeout handling and increase Tesla's timeout to 5 seconds.
## [0.3.1] - 2024-10-14
### Added
- **Error Handling**: Introduced a new module `LlmComposer.Errors` with a custom `MissingKeyError` for better error management.
- **Removed Legacy Code**: Removed the `get_messages/4` function from `LlmComposer` to streamline message handling.
## [0.3.0] - 2024-10-10
### Added
- **System Prompt Handling**: Added support for an optional system prompt in `run_completion/3`. The `system_prompt` is now treated as `nil` when not provided.
- **Custom Message Flow Example**: Updated the `README.md` with an example of how to use the `run_completion/3` function directly with a custom message history.
- **Nil Message Handling in Models**: Handling the `nil` case when system_prompt not provided
## [0.2.0] - 2024-10-10
### Added
- Initial release with support for basic message handling, interaction with OpenAI and Ollama models, and a foundational structure for model settings and function execution.
---
[0.20.2]: https://github.com/doofinder/llm_composer/compare/0.20.1...0.20.2
[0.20.1]: https://github.com/doofinder/llm_composer/compare/0.20.0...0.20.1
[0.20.0]: https://github.com/doofinder/llm_composer/compare/0.19.6...0.20.0
[0.19.6]: https://github.com/doofinder/llm_composer/compare/0.19.5...0.19.6
[0.19.5]: https://github.com/doofinder/llm_composer/compare/0.19.4...0.19.5
[0.19.4]: https://github.com/doofinder/llm_composer/compare/0.19.3...0.19.4
[0.19.3]: https://github.com/doofinder/llm_composer/compare/0.19.2...0.19.3
[0.19.2]: https://github.com/doofinder/llm_composer/compare/0.19.1...0.19.2
[0.19.1]: https://github.com/doofinder/llm_composer/compare/0.19.0...0.19.1
[0.19.0]: https://github.com/doofinder/llm_composer/compare/0.18.2...0.19.0
[0.18.2]: https://github.com/doofinder/llm_composer/compare/0.18.1...0.18.2
[0.18.1]: https://github.com/doofinder/llm_composer/compare/0.18.0...0.18.1
[0.18.0]: https://github.com/doofinder/llm_composer/compare/0.17.1...0.18.0
[0.17.1]: https://github.com/doofinder/llm_composer/compare/0.17.0...0.17.1
[0.17.0]: https://github.com/doofinder/llm_composer/compare/0.16.2...0.17.0
[0.16.2]: https://github.com/doofinder/llm_composer/compare/0.16.1...0.16.2
[0.16.1]: https://github.com/doofinder/llm_composer/compare/0.16.0...0.16.1
[0.16.0]: https://github.com/doofinder/llm_composer/compare/0.15.0...0.16.0
[0.15.0]: https://github.com/doofinder/llm_composer/compare/0.14.2...0.15.0
[0.14.2]: https://github.com/doofinder/llm_composer/compare/0.14.1...0.14.2
[0.14.1]: https://github.com/doofinder/llm_composer/compare/0.14.0...0.14.1
[0.14.0]: https://github.com/doofinder/llm_composer/compare/0.13.1...0.14.0
[0.13.1]: https://github.com/doofinder/llm_composer/compare/0.13.0...0.13.1
[0.13.0]: https://github.com/doofinder/llm_composer/compare/0.12.3...0.13.0
[0.12.3]: https://github.com/doofinder/llm_composer/compare/0.12.2...0.12.3
[0.12.2]: https://github.com/doofinder/llm_composer/compare/0.12.0...0.12.2
[0.12.0]: https://github.com/doofinder/llm_composer/compare/0.11.2...0.12.0
[0.11.2]: https://github.com/doofinder/llm_composer/compare/0.11.1...0.11.2
[0.11.1]: https://github.com/doofinder/llm_composer/compare/0.11.0...0.11.1
[0.11.0]: https://github.com/doofinder/llm_composer/compare/0.10.0...0.11.0
[0.10.0]: https://github.com/doofinder/llm_composer/compare/0.9.0...0.10.0
[0.9.0]: https://github.com/doofinder/llm_composer/compare/0.8.0...0.9.0
[0.8.0]: https://github.com/doofinder/llm_composer/compare/0.7.0...0.8.0
[0.7.0]: https://github.com/doofinder/llm_composer/compare/0.6.0...0.7.0
[0.6.0]: https://github.com/doofinder/llm_composer/compare/0.5.5...0.6.0
[0.5.5]: https://github.com/doofinder/llm_composer/compare/0.5.4...0.5.5
[0.5.4]: https://github.com/doofinder/llm_composer/compare/0.5.3...0.5.4
[0.5.3]: https://github.com/doofinder/llm_composer/compare/0.5.2...0.5.3
[0.5.2]: https://github.com/doofinder/llm_composer/compare/0.5.1...0.5.2
[0.5.1]: https://github.com/doofinder/llm_composer/compare/0.5.0...0.5.1
[0.3.5]: https://github.com/doofinder/llm_composer/compare/0.3.4...0.3.5
[0.5.0]: https://github.com/doofinder/llm_composer/compare/0.3.5...0.5.0
[0.3.4]: https://github.com/doofinder/llm_composer/compare/0.3.3...0.3.4
[0.3.3]: https://github.com/doofinder/llm_composer/compare/0.3.2...0.3.3
[0.3.2]: https://github.com/doofinder/llm_composer/compare/0.3.1...0.3.2
[0.3.1]: https://github.com/doofinder/llm_composer/compare/0.3.0...0.3.1
[0.3.0]: https://github.com/doofinder/llm_composer/compare/0.2.0...0.3.0
[0.2.0]: https://github.com/doofinder/llm_composer/compare/d9f96d55859300d779d9c3899b4c33578bb2e362...0.2.0
[first commit]: https://github.com/doofinder/llm_composer/commit/d9f96d55859300d779d9c3899b4c33578bb2e362