Skip to main content

Module engine

Module engine 

Source
Expand description

The flow interpreter — doc 48’s “the daemon runs the flow”.

The loop is deliberately tiny: run the current node, get either the next node id or a terminal, append a trace step, repeat. All the side effects a component needs (speak, collect a DTMF digit, ring the human, record, transfer, hang up) sit behind the FlowEffects trait — the “component-implementation seam” doc 48 keeps the engine generic over. The daemon supplies the real impl (wiring wavekat-tts for prompts, RFC 4733 receive for DTMF, the normal incoming-call path for ring, the recording pipeline for message, REFER for transfer); tests supply a scripted mock. Nothing here touches SQLite, the renderer, sync, or cpal — the whole module stays extractable.

Control-flow logic (menu retry counting, hours branching) lives here and is pure; only the actual audio/telephony effects cross the trait. That is what makes a full call testable with no call.

This crate owns the FlowEffects trait definition; the daemon keeps its live CallFlowEffects impl in its own codebase.

Enums§

Digit
A DTMF key a caller can press.
RingOutcome
Result of a ring node.

Traits§

FlowEffects
The side effects the components need. The engine calls these; the impl performs the telephony/audio. &mut self because a real impl holds the live call. Methods return anyhow::Result so the daemon impl can surface call-dropped / device errors uniformly; the engine treats any Err as “the call is gone” and aborts with a trace.

Functions§

run
Run a validated flow to completion against fx, filling trace.