Current section

Files

Jump to
orchid 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.5.2] - 2026-01-17
> **Robustness & Cleanup**.
> This release focuses on standardizing return types, fixing edge cases in asynchronous execution, and cleaning up internal identifiers to be less dependent on list indices.
### Fixed
- **Async Executor**: Fixed an issue where `Orchid.Executor.Async` would discard the context payload when a step returned `{:special, context}`. It now correctly wraps the payload in the error reason `{:core_executor_not_support_special, context}`.
- **Pipeline Consistency**: `Orchid.Pipeline.run/2` now consistently returns an `Orchid.Operon.Response` struct (wrapping the error) even when the middleware stack is empty or hits the sink, preventing format mismatch errors.
### Added
- **Custom Core Hook**: Added `:core_hook` support in `Orchid.WorkflowCtx` config. This allows replacing `Orchid.Runner.Hooks.Core` with a custom module, which is useful for specialized execution strategies or testing mocks.
- **Step Comparison**: Added `Orchid.Step.ID.same?/2` to check if two steps share the same Input/Output interface.
### Changed
- **Recipe Validation**: `Orchid.Recipe.validate_steps/2` no longer includes the step index (`idx`) in `{:invalid_step_option, ...}` errors. This aligns with the roadmap goal of moving away from order-based identification.
- **Internal ID Logic**: Refactored `Orchid.Step.ID.finger_print/2`. The `as_num?` option is replaced by `headless?`. It no longer returns an integer hash but simpler tuples (`{in, out}` or `{impl, in, out}`), making it more predictable for debugging.
- **Context API**: Renamed Orchid.WorkflowCtx's `add_step/2` to `add_depth/2` to better reflect its purpose of tracking call stack depth in nested workflows.
## [0.5.1] - 2026-01-04
> **Documentation & Refactoring**.
> This release polishes the internal architecture, making the `WorkflowCtx` the single source of truth for configuration, and significantly improves internal documentation.
### Changed
- **Configuration Source of Truth**: `Orchid.run/3` now initializes `WorkflowCtx` earlier. Consequently, `Orchid.Operon.Request` no longer carries `executor_and_opts` directly; it is now dynamically resolved from `WorkflowCtx`. This allows Operons to swap Executors dynamically (e.g., switching to a GPU-optimized executor based on input).
- **Scheduler Internals**:
- Reordered fields in `Orchid.Scheduler.Context` for better memory alignment (maybe).
- **Docs**: Added detailed explanation on why Orchid uses a mix of `List` (for deterministic order) and `MapSet` (for O(1) lookups) in the Scheduler context.
- **Code Generation**: `Orchid.Runner` now uses `apply/3` to invoke step implementations. This reduces compile-time dependency warnings when creating dynamic workflows.
### Fixed
- **Execution History**: Fixed an inconsistency in `Scheduler.merge_result/3` where execution history tracking was slightly malformed (removed the index from history tuples).
- **Typing**: Relaxed type specs for `telemetry_meta` and `assigns` in `Runner` to generic `map()` to accommodate more flexible plugin data.
## [0.5.0] - 2026-01-02
> _Happy New Year!_
This is the first release of the year, bringing a new plugin architecture to Orchid. May your workflows bloom beautifully this year!
### Breaking Changes
- **Nested Step Error Handling**: `Orchid.Step.NestedStep` now returns `{:error, {:nested_step_execution_failed, inner_context}}` instead of just the reason. This allows parent workflows to access the failed child's context for potential recovery or debugging.
- **Hook Protocol**: The `Orchid.Runner.Hook` behavior now supports a third return type: `{:special, any()}`. Custom hooks implementing stricter type checks may need updates.
- **Default Executors**: The built-in `Serial` and `Async` executors will now explicitly error with `{:core_executor_not_support_special, ...}` if a step returns a `{:special, ...}` tuple. This signals that a specialized executor (e.g., from a Session plugin) is required to handle such states.
### Added
- **Plugin Support (Special Return)**: Introduced `{:special, payload}` as a first-class return type in `Orchid.Runner`. This mechanism is designed for plugins (like `Orchid.Session`) to implement flow control logic like **Pause**, **Interrupt**, or **Yield** without abusing the Error channel.
- **Telemetry**: Added a new event `[:orchid, :step, :special]` to track steps that exit with the special status.
- **Error Kinds**: Added `:logic_or_exception` to `Orchid.Error` kinds to better describe failures caught in async tasks.
### Changed
- **Async Executor**: Improved robustness by explicitly flushing the monitor message (`:DOWN`) when a task completes successfully, preventing potential race conditions or mailbox pollution.
- **Dependencies**: Updated `lib/orchid/step/id.ex` to depend on `Orchid.Step` alias correctly.
- **Documentation**: Updated README roadmap and translated more comments in `Async` executor to English.
- **Copyright**: Updated License year to 2026.
### Internal
- **Refactoring**: `Orchid.WorkflowCtx` now uses pipeline operators for cleaner config/baggage merging logic.
## [0.4.1] - 2025-12-27
### Refinements (Improvements to 0.4.0)
- **Context Propagation**: Introduced "Baggage" to `Orchid.WorkflowCtx`. You can now pass global metadata via `Orchid.run(..., baggage: map)` which propagates vertically into nested steps.
- **Hooks Resolution**: Global hooks are now correctly resolved from the `WorkflowCtx` configuration instead of the recipe options. This aligns the behavior with the new Context architecture introduced in 0.4.0.
- **Error Reporting**: The cyclic dependency error now returns useful `Step` structs (`{:cyclic, steps}`) instead of opaque indices.
### Fixed
- **Validation**: Fixed a variable scope issue in `Recipe.validate_steps` that could cause a crash during cycle detection.
- **Key Normalization**: Moved IO key normalization logic to `Orchid.Step.ID` to fix potential inconsistencies between static checks and runtime execution.
- **Telemetry**: Fixed the injection timing of `__reporter_ctx__` to ensuring metadata is available during the entire step lifecycle.
### Docs
- **Internals**: Added comprehensive documentation for `Orchid.Error`, `Orchid.Scheduler.Context`, and `Orchid.WorkflowCtx`.
- **Tests**: Translated integration test comments to English.
## [0.4.0] - 2025-12-26
### Breaking Changes
- **Context & Options**: `Orchid.run/3` now strictly filters input options. Arbitrary keys are no longer implicitly merged into step options. User-defined metadata/context must now be passed via the new `:baggage` option.
- **Error Handling**: Execution failures are now returned as `{:error, %Orchid.Error{}}`. The `Orchid.Error` struct (an Exception) contains the failure reason, the step fingerprint, the failure kind (`:logic`, `:exception`, `:exit`), and the **execution context** (enabling partial result recovery).
- **Telemetry**: Renamed the event `[:orchid, :step, :stop]` to `[:orchid, :step, :done]` to distinct completion from termination.
- **Step DSL**: The `nested?/0` callback has been replaced by the module attribute `@orchid_step_nested boolean` when using `Orchid.Step`.
- **Plugin**: Removed `Orchid.Plugin` module as it was unused and superseded by the Operon/Hook architecture.
### Added
- **Workflow Context**: Introduced `Orchid.WorkflowCtx` to explicitly manage execution scope, nested paths, configuration, and baggage throughout the pipeline.
- **API**: Added `Orchid.run_with_ctx/3` to support executing recipes with a pre-initialized context (e.g., for sub-workflows or resuming).
- **Identification**: Introduced `Orchid.Step.ID` to generate deterministic fingerprints/IDs for steps.
- **Helpers**: Added `Orchid.Step.report/3` to standardize progress reporting via Telemetry.
### Changed
- **Executor**: Executors (`Async` and `Serial`) now capture the runtime context upon failure and wrap it in `Orchid.Error`, preventing data loss during crashes.
- **Internals**: Refactored `Orchid.Runner` to propagate `WorkflowCtx` instead of loose keyword lists.
## [0.3.5] - 2025-12-23
### Changed
- **Executor**: Refined the return signature of `Orchid.Executor.execute_next_step/1`. It now returns `{:cont, context}` for successful step execution, providing a clearer distinction between running, stuck, and done states.
- **API Visibility**: Changed Orchid.inject_opts_into_recipe/2 from public (`def`) to private (`defp`) to reduce the public API surface area.
- **Structs**: initialized default values for `Orchid.Operon.Request`. `assigns` now defaults to `%{}` (was nil) and `operon_options` to `[]`.
- **Packaging**: Included `CHANGELOG.md` in the Hex package definition and documentation extras in `mix.exs`.
### Fixed
- **Types**: Added missing type specifications for `Orchid.Pipeline.run/2` and corrected the spec for `Orchid.Recipe.assign_options/3`.
### Documentation
- **Roadmap**: Updated `README.md` to reflect plans for `OrchidInstruments` and `OrchidPersistence`.
## [0.3.4] - 2025-12-22
### Added
- **Executor**: Added `Orchid.Executor.execute_next_step/1`. This helper encapsulates logic for fetching the next ready step and detecting "stuck" or "done" states, simplifying custom Executor implementation and debugging.
- **Recipe**: Enhanced `Orchid.Recipe.assign_options/3`. It now accepts a transformation function `(Step.t() -> Step.t())` as the third argument, allowing dynamic modification of step configurations.
- **Runner**: Updated `Orchid.Runner.run/4`. Added an optional `initial_assigns` argument to inject context assigns when running individual steps.
### Changed
- **Executor.Serial**: Refactored the internal loop to utilize the new `execute_next_step/1` helper.
- **Scheduler**: Updated the internal structure of `Context.history`. It now records `{Step.t(), step_index, MapSet<ProducedKeys>}` to track keys produced by each step more accurately.
- **Mix**: Configured `elixirc_paths` in `mix.exs`. Files in `test/support` are now automatically compiled only in the `:test` environment, removing the need for manual requires in `test_helper.exs`.
## [0.3.3] - 2025-12-18
### Fixed
- **Scheduler**: Fixed a potential crash in executor caused by invoking a scheduler function signature,`mark_running/2`.
- **Dialyzer**: Resolved opaque type warnings related to `Scheduler.build/2` by adding explicit ignore rules.
### Changed
- **Error Handling**: Renamed the error tag in `NestedStep` from `:nested_execution_failed` to `:nested_step_execution_failed` for better clarity.
- **Internal API**: Renamed `step_default_opts` to `step_opts` within `Orchid.Runner.Context` to better reflect that these are the final merged options.
- **Refactoring**: Consolidated `Orchid.Scheduler.Context` definition back into `lib/orchid/scheduler.ex` to improve module cohesion and reduce file fragmentation.
- **Custome Executor**: Changed `mark_running/2` into `mark_running_steps/3` to allow pushing running steps when retry.
- **Code Style**: Unified codebase to use single-line function definitions (`def ..., do: ...`) for consistency.
### Documentation
- **Internationalization**: Enhanced `README.md` and translated core module docstrings (Executor, Async, Serial) from Chinese to English.
- **Architecture**: Updated architecture diagrams in `README.md` to reflect the current data flow more accurately.
## [0.3.2] - 2025-12-15
### Added
- **Nested Recipes**: Introduced `Orchid.Step.NestedStep` to treat entire recipes as atomic steps.
- **Parameter Mapping**: Added `input_map` and `output_map` support in `NestedStep` to rename parameters across boundaries.
- **Global Configuration**: Added `global_hooks_stack` support in `Orchid.run/3` options.
- **Plugin Infrastructure**: Laid the groundwork for plugin integration via standard option injection.
### Changed
- **Option Inheritance**: Improved the option merging strategy (`Orchid.inject_opts_into_recipe`).
- Hooks are now **stacked** (Parent ++ Child).
- Executors and other options now follow a **Base + Specific** inheritance rule (Child overrides Parent defaults).
## [0.3.1] - 2025-12-12
### Added
- `:executor_and_opts` options in `Orchid.run/3`