For the complete documentation index, see llms.txt. This page is also available as Markdown.

Wait, Input, and Resume

Suspend a flow for external input and continue the same execution

kitaru.wait(...) is the durable suspension primitive for human-in-the-loop and external-input workflows.

When your flow reaches wait(...), what happens next depends on the environment:

  • Local interactive runs (terminal with stdin/stdout): the runtime prompts for input directly in the same terminal and the flow continues in-process.

  • Non-interactive runs (remote orchestrators, CI, piped output, MCP): the execution moves to waiting status and input must be supplied later via the client, CLI, or MCP.

Basic pattern

from kitaru import flow
import kitaru

@flow
def publish_flow(topic: str) -> str:
    approved = kitaru.wait(
        schema=bool,
        name="approve_publish",
        question=f"Approve publishing {topic}?",
        metadata={"topic": topic},
    )
    if not approved:
        return f"REJECTED: {topic}"
    return f"PUBLISHED: {topic}"

Get the current execution ID inside a flow

If code is already running inside a Kitaru flow or checkpoint, use kitaru.current_execution_id() to read the active execution ID:

This is useful when a flow needs to print follow-up CLI commands, name per-execution side resources, or attach the execution ID to application logs. Outside a running Kitaru flow or checkpoint, it returns None.

kitaru.wait() itself must run at flow scope, before or after checkpoint calls, not inside a @checkpoint. For why this rule exists and how to split work around a wait, see Where wait() can be called.

Timeout behavior

By default, kitaru.wait(...) gives the runner up to 600 seconds to receive inline input before pausing the execution:

timeout controls how long the runner keeps polling — it is not an expiration on the wait record itself. If the timeout elapses without input, the execution moves to waiting status and can still be resolved externally at any time.

Resolve input externally (non-interactive runs)

When the flow is running in a non-interactive context (or after the runner has timed out and paused), resolve the pending wait from Python or the CLI.

From Python

If the execution does not continue automatically after input (e.g. the original runner already exited), call resume(...):

To abort a wait instead of continuing:

From CLI

The CLI auto-detects the single pending wait. For interactive review (with JSON schema display, continue/abort choices, and multi-execution sweep):

To abort a wait instead of continuing:

Resume is only needed when the execution did not continue automatically:

Validation behavior

Input is validated against the wait schema:

  • invalid input raises kitaru.KitaruWaitValidationError

  • execution stays in waiting until valid input is supplied

Example in this repository

  1. Run the command above — it starts the flow and blocks.

  2. If you are in an interactive terminal, the runtime prompts for input directly. Type your answer and the flow continues.

  3. If the run is non-interactive (or you want to resolve from elsewhere), the script prints fallback kitaru executions input ... and kitaru executions resume ... commands you can run in a second terminal.

Automated CI coverage for the same flow lives in tests/test_phase15_wait_example.py.

For the broader catalog, see Examples.

Last updated

Was this helpful?