Expand description
Everything the reducer asks the outside world to do.
Cmd values are inert data structures. The reducer returns them
alongside each new State; effect::EffectRunner::dispatch then
turns them into real work (spawning tokio tasks, writing files,
hitting HTTP endpoints, killing processes). The reducer itself
never performs any I/O.
This is the “effects as data” pattern from Elm/Redux. Three payoffs this rewrite relies on:
- Testable reducer. Assertions are
state, cmds = update(...) ; assert_eq!(cmds[0], Cmd::CallModel { … }). No tokio, no mocks, no filesystem. - Uniform middleware. Retry, tracing, rate-limiting wrap the dispatcher once instead of being re-implemented per adapter.
- Replayable sessions.
--recorddumps everyMsg; the effects the reducer asked for are fully determined by the Msg log + initial state, so--replayis a pure fold.
Structs§
- Chat
Request - Inputs a model needs to generate a turn. Built by the reducer from
Session+Settings+ currentMERMAID.mdcontext. Pure data — no provider-specific knowledge here (that’s inproviders::model::*::chat). - Tool
Definition - Provider-agnostic tool definition sent in the request. Concrete
adapters (
providers::model::ollama, etc.) translate this into whatever wire shape their API expects.
Enums§
- Cmd
- A single side-effect request. Most variants are one-shot;
CallModelandExecuteToolspawn long-running tasks inside a per-turnTurnScope.