Helpers for strategies that process data in grouped batches.
Strategies remain in full control of the episode loop — Batch provides
a lightweight struct for chunking data, tracking progress through groups,
and collecting results. No new step types are introduced; strategies
continue using :tool_call and :synthesize as normal.
Usage
# In strategy init — load items, group them, initialize batch
items = load_all_items(product_id)
batch = Cyclium.Batch.init(Cyclium.Batch.group_by(items, &base_item_id/1))
# In next_step — drive the loop
case Cyclium.Batch.current_group(state.batch) do
nil -> :converge
{group_key, items} -> {:synthesize, build_prompt(group_key, items)}
end
# In handle_result — advance to next group
batch = Cyclium.Batch.advance(state.batch, parsed_result)
{:ok, %{state | batch: batch}}
Summary
Functions
Advance to the next group, storing the result from the current one.
Chunk a flat list into groups of size.
Get the current group to process.
Check if all groups have been processed.
Group items by a key function.
Total number of groups.
Initialize batch state from a list of {group_key, items} tuples.
Number of groups already processed.
Types
@type t() :: %Cyclium.Batch{ current_index: non_neg_integer(), groups: [{term(), [term()]}], results: [term()] }
Functions
Advance to the next group, storing the result from the current one.
@spec chunk([term()], pos_integer()) :: [{non_neg_integer(), [term()]}]
Chunk a flat list into groups of size.
Returns {index, items} tuples suitable for init/1.
Get the current group to process.
Returns {group_key, items} or nil when all groups are done.
Check if all groups have been processed.
Group items by a key function.
Returns {group_key, items} tuples suitable for init/1.
@spec group_count(t()) :: non_neg_integer()
Total number of groups.
Initialize batch state from a list of {group_key, items} tuples.
@spec processed_count(t()) :: non_neg_integer()
Number of groups already processed.