Skip to main content
A flow splits a conversation into stages. Each stage has its own instructions and its own tools, and the agent moves from one to the next when a condition is met: the customer wants to book, a tool answered, a variable has a value. An agent without a flow works on a single prompt, as always. In the Builder, the Flow section shows the flow as a canvas. Everything you build there is also available from the public API, the MCP server and the CLI, with the same rules.

How a flow works

A flow is a graph: nodes (the steps) joined by edges (the ways out of each step). The conversation starts at entry_node_id. At the end of every turn, the current node’s edges are evaluated in this order:
  1. tool_result and variable conditions, which need no model, by priority (highest first).
  2. Every llm_decision condition, in a single model call: the model picks the way out that matches, guided by each description.
  3. The always edge, which is the explicit “else”.
  4. If nothing applies, the conversation stays where it is.
Global nodes (global_nodes) can be entered from any stage through their global_condition, and when they finish the conversation returns to the stage it came from. Useful for “the customer asks for a human” or “the customer wants to cancel”.
A conversation stage (prompt) cannot have an always edge. The agent would leave the stage on the very first turn in which the model does not choose another way out. Use llm_decision, tool_result or variable instead. always is fine on say, tool and set_variables nodes, which do not wait for the customer. The opposite also holds: an llm_decision edge only works from a prompt stage, because the other steps do not talk and the model never chooses.

A minimal flow

Qualify the caller, book if they want to, and say goodbye:
Every field, every condition and every rule is in the Flow schema of the API reference.

Read the flow

GET /v1/agents/{id} returns it in config.flow, and GET /v1/agents/{id}/versions/{version} in flow. It is null when the agent has no flow.

Change the flow

Send the whole graph in flow with PATCH /v1/agents/{id}. It replaces the current one: there is no way to send just one node, so read the flow first, change it and send it back.
  • "flow": null removes the flow, and the agent goes back to working on its prompt.
  • Like any configuration change, it is saved as a new draft version. Publish it with POST /v1/agents/{id}/publish so calls use it.
  • Pass expected_version (the current_version you read) so you do not overwrite a change made in the Builder in the meantime.
If the graph breaks a rule (an edge to a node that does not exist, an always edge on a stage, an llm_decision from a step that does not talk, a blank description, a tool the agent does not have), the answer is 400 invalid_flow and nothing is saved, not even the name or status sent in the same request. A node can only name the agent’s tools: built-in ones and the ones in the version’s tool_ids.

From the MCP server and the CLI

  • MCP: get_agent returns the flow and update_agent accepts flow with the same rules. Your AI client can read the flow, change it and send it back whole.
  • CLI: ryvo agents get <id> shows a flow line with the number of nodes and the entry stage; add --json to see the whole graph. To change it, pass the body with --data: