Two features lift Keikaku’s generators from producers to coroutines. The first is bidirectional communication. Inside a sequence, receive() obtains a value sent by the caller, and the caller sends it with transmit(gen, value). The documented echo generator loops forever, receiving a message and yielding "You said: " + text(msg); after proceed(gen) starts it, transmit(gen, "Hello") returns "You said: Hello". This two-way channel is what makes a generator a consumer as well as a producer.

The second is exception injection. disrupt(gen, error) raises an exception inside a running generator at its current suspension point. Paired with an in-generator attempt/recover, the generator can catch the injected fault and continue rather than terminate: the documented robust_task and worker generators recover from an injected "Network Failure" / "System overload" and keep yielding. Together, bidirectional communication and injection make a sequence behave like a supervised, signalable process, reusing the same attempt/recover error model the rest of the language uses. This is the machinery the async layer is built on.