How to Use Variables for Shared State in Flows#
Prerequisites
This guide assumes familiarity with Flows
When building Flows, you may need a way to preserve information as it moves from one step to another. WayFlow provides this through Variable, which serves as the flow’s state — a place where values can be stored, accessed, and updated throughout execution.
Why to use Variable?
Shared state: Holds data that multiple steps can share.
Intermediate results: Store partial results and reuse them later.
Simpler data flow: Avoid passing outputs between every step, persist them as state using Variable.
This guide will show you how to:
Define a Variable in a Flow.
Read and write its value with VariableStep.
In this guide, you will see a simple example including defining a Variable that stores a list of user feedback,
using VariableStep to insert new feedback into the list and read all collected feedback.
Define a Variable#
To define a variable, you need to define it with a name, type and optionally, a default value.
The type of variable determines the kind of data it can hold and is defined using Property.
In this case, our feedback_variable has the type of ListProperty and the item_type of StringProperty.
1from wayflowcore.variable import Variable
2from wayflowcore.property import ListProperty, StringProperty
3
4feedback_variable = Variable(
5 name="user_feedback",
6 type=ListProperty(item_type=StringProperty()),
7 description="list of user feedback",
8 default_value=[],
9)
Define Flow Steps#
We will define a simple flow including the following steps.
1from wayflowcore.steps import StartStep, OutputMessageStep, VariableStep
2from wayflowcore.property import StringProperty
3from wayflowcore.variable import VariableWriteOperation
4
5FEEDBACK_1 = "feedback_1"
6FEEDBACK_2 = "feedback_2"
7
8start_step = StartStep(
9 name="start_step",
10 input_descriptors=[StringProperty(FEEDBACK_1), StringProperty(FEEDBACK_2)],
11)
12
13write_feedback_1 = VariableStep(
14 name="write_var_step_1",
15 write_variables=[feedback_variable],
16 write_operations=VariableWriteOperation.INSERT,
17)
18
19write_feedback_2 = VariableStep(
20 name="write_var_step_2",
21 write_variables=[feedback_variable],
22 write_operations=VariableWriteOperation.INSERT,
23)
24
25read_feedback = VariableStep(
26 name="read_var_step",
27 read_variables=[feedback_variable],
28)
29
30output_step = OutputMessageStep("Collected feedback: {{ feedback }}", name="output_step")
For simplicity, we pass initial feedback to the start_step, which then routes values to write_feedback_1 and write_feedback_2.
In practice, those inputs could come from other steps (e.g. ToolExecutionStep).
When updating some variables, the VariableStep requires the write_variables that it writes to. It also accepts the following options of write operations:
VariableWriteOperation.OVERWRITE(or'overwrite') works on any type of variable to replace its value with the incoming value.VariableWriteOperation.MERGE(or'merge') updates aVariableof type dict (resp. list),VariableWriteOperation.INSERT(or'insert') operation can be used to append a single element at the end of a list.
Here, we choose insert as we want to append new user feedback to the our list.
The VariableStep can also read one or more variables, via the read_variables parameter.
The VariableStep can perform both writes and reads of multiple variables at the same time.
If you configure a step to both write and read a given variable, the value will be written first, and the updated variable will be used for the read operation.
In general, the input and output descriptors of the VariableStep correspond to the properties referenced by the variables being written and/or read in this step, respectively.
For example, if the step is configured to overwrite a Variable(name="manager", type=DictProperty()), to extend a Variable(name="employees", type=ListProperty(item_type=DictProperty("employee")), and to read back the updated value of the employee list, the step would have the following descriptors:
An input descriptor
DictProperty("manager"), to overwrite the full manager variable;An input descriptor
DictProperty("employee"), since the extend operation expects a single item of the employees list;An output descriptor
ListProperty("employees", item_type=DictProperty("employee"))
Define a Flow with Variable#
Now we connect everything into a flow: two write steps add feedback, and a read step collects it all for output.
1from wayflowcore.controlconnection import ControlFlowEdge
2from wayflowcore.dataconnection import DataFlowEdge
3from wayflowcore.flow import Flow
4
5flow = Flow(
6 begin_step=start_step,
7 control_flow_edges=[
8 ControlFlowEdge(start_step, write_feedback_1),
9 ControlFlowEdge(write_feedback_1, write_feedback_2),
10 ControlFlowEdge(write_feedback_2, read_feedback),
11 ControlFlowEdge(read_feedback, output_step),
12 ControlFlowEdge(output_step, None),
13 ],
14 data_flow_edges=[
15 DataFlowEdge(start_step, FEEDBACK_1, write_feedback_1, feedback_variable.name),
16 DataFlowEdge(start_step, FEEDBACK_2, write_feedback_2, feedback_variable.name),
17 DataFlowEdge(read_feedback, feedback_variable.name, output_step, "feedback"),
18 ],
19 variables=[feedback_variable],
20)
Remember to include your defined variables in the Flow’s variables parameter.
Execute the Flow#
Finally, run the flow:
1conv = flow.start_conversation(
2 inputs={
3 FEEDBACK_1: "Very good!",
4 FEEDBACK_2: "Need to improve!",
5 }
6)
7conv.execute()
8
9result = conv.get_last_message().content
10print(result)
11# >>> Collected feedback: ["Very good!", "Need to improve!"]
Agent Spec Exporting/Loading#
You can export the assistant configuration to its Agent Spec configuration using the AgentSpecExporter.
from wayflowcore.agentspec import AgentSpecExporter
serialized_assistant = AgentSpecExporter().to_yaml(flow)
Here is what the Agent Spec representation will look like ↓
Click here to see the AgentSpec assistant configuration.
component_type: ExtendedFlow
id: b41482ac-31b3-4117-805e-cb34931e9971
name: flow_3fc1343f__auto
description: ''
metadata:
__metadata_info__: {}
inputs:
- type: string
title: feedback_1
- type: string
title: feedback_2
outputs:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
- description: the message added to the messages list
type: string
title: output_message
start_node:
$component_ref: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
nodes:
- $component_ref: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
- $component_ref: be27d2dc-0185-41b0-bbbc-31060306b34c
- $component_ref: 4991b600-4fe1-4e46-82f8-6d0764989291
- $component_ref: e8e2df93-abc9-492a-9c0b-92c4a68895b9
- $component_ref: bd2331f9-c336-446d-b6e8-5c4365e4327b
- $component_ref: 9834131e-83bf-4927-81bc-89965824271f
control_flow_connections:
- component_type: ControlFlowEdge
id: c98164c9-eeaa-42da-9f42-c8e574b34c4a
name: start_step_to_write_var_step_1_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
from_branch: null
to_node:
$component_ref: be27d2dc-0185-41b0-bbbc-31060306b34c
- component_type: ControlFlowEdge
id: 95b902ad-6e56-4587-9e92-d725c955f5b1
name: write_var_step_1_to_write_var_step_2_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: be27d2dc-0185-41b0-bbbc-31060306b34c
from_branch: null
to_node:
$component_ref: 4991b600-4fe1-4e46-82f8-6d0764989291
- component_type: ControlFlowEdge
id: 57bafe45-a33c-44bc-a21a-51205da9a8d8
name: write_var_step_2_to_read_var_step_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: 4991b600-4fe1-4e46-82f8-6d0764989291
from_branch: null
to_node:
$component_ref: e8e2df93-abc9-492a-9c0b-92c4a68895b9
- component_type: ControlFlowEdge
id: 621e214c-4048-409d-920d-7af0a09dd46a
name: read_var_step_to_output_step_control_flow_edge
description: null
metadata:
__metadata_info__: {}
from_node:
$component_ref: e8e2df93-abc9-492a-9c0b-92c4a68895b9
from_branch: null
to_node:
$component_ref: bd2331f9-c336-446d-b6e8-5c4365e4327b
- component_type: ControlFlowEdge
id: 4325173c-575c-41d1-9222-8f263267ec93
name: output_step_to_None End node_control_flow_edge
description: null
metadata: {}
from_node:
$component_ref: bd2331f9-c336-446d-b6e8-5c4365e4327b
from_branch: null
to_node:
$component_ref: 9834131e-83bf-4927-81bc-89965824271f
data_flow_connections:
- component_type: DataFlowEdge
id: 29904c9b-8ff3-410c-a484-d95a9f4f9248
name: start_step_feedback_1_to_write_var_step_1_user_feedback_data_flow_edge
description: null
metadata:
__metadata_info__: {}
source_node:
$component_ref: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
source_output: feedback_1
destination_node:
$component_ref: be27d2dc-0185-41b0-bbbc-31060306b34c
destination_input: user_feedback
- component_type: DataFlowEdge
id: 5440b896-e11b-48b3-ae83-4e0832f87bc6
name: start_step_feedback_2_to_write_var_step_2_user_feedback_data_flow_edge
description: null
metadata:
__metadata_info__: {}
source_node:
$component_ref: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
source_output: feedback_2
destination_node:
$component_ref: 4991b600-4fe1-4e46-82f8-6d0764989291
destination_input: user_feedback
- component_type: DataFlowEdge
id: ff59cde4-e95d-4caf-b8b3-0e9097013bb2
name: read_var_step_user_feedback_to_output_step_feedback_data_flow_edge
description: null
metadata:
__metadata_info__: {}
source_node:
$component_ref: e8e2df93-abc9-492a-9c0b-92c4a68895b9
source_output: user_feedback
destination_node:
$component_ref: bd2331f9-c336-446d-b6e8-5c4365e4327b
destination_input: feedback
- component_type: DataFlowEdge
id: f003fdad-8e7c-4d24-914f-1f30fa393f0d
name: read_var_step_user_feedback_to_None End node_user_feedback_data_flow_edge
description: null
metadata: {}
source_node:
$component_ref: e8e2df93-abc9-492a-9c0b-92c4a68895b9
source_output: user_feedback
destination_node:
$component_ref: 9834131e-83bf-4927-81bc-89965824271f
destination_input: user_feedback
- component_type: DataFlowEdge
id: 200b7819-9b5a-449e-9ce0-dbf1c78d8430
name: output_step_output_message_to_None End node_output_message_data_flow_edge
description: null
metadata: {}
source_node:
$component_ref: bd2331f9-c336-446d-b6e8-5c4365e4327b
source_output: output_message
destination_node:
$component_ref: 9834131e-83bf-4927-81bc-89965824271f
destination_input: output_message
context_providers: []
state:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
component_plugin_name: FlowPlugin
component_plugin_version: 26.1.0.dev4
$referenced_components:
57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b:
component_type: StartNode
id: 57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b
name: start_step
description: ''
metadata:
__metadata_info__: {}
inputs:
- type: string
title: feedback_1
- type: string
title: feedback_2
outputs:
- type: string
title: feedback_1
- type: string
title: feedback_2
branches:
- next
be27d2dc-0185-41b0-bbbc-31060306b34c:
component_type: PluginVariableNode
id: be27d2dc-0185-41b0-bbbc-31060306b34c
name: write_var_step_1
description: ''
metadata:
__metadata_info__: {}
inputs:
- description: list of user feedback (single element)
type: string
title: user_feedback
outputs: []
branches:
- next
input_mapping: {}
output_mapping: {}
write_variables:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
read_variables: []
write_operations:
user_feedback: insert
component_plugin_name: NodesPlugin
component_plugin_version: 26.1.0.dev4
4991b600-4fe1-4e46-82f8-6d0764989291:
component_type: PluginVariableNode
id: 4991b600-4fe1-4e46-82f8-6d0764989291
name: write_var_step_2
description: ''
metadata:
__metadata_info__: {}
inputs:
- description: list of user feedback (single element)
type: string
title: user_feedback
outputs: []
branches:
- next
input_mapping: {}
output_mapping: {}
write_variables:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
read_variables: []
write_operations:
user_feedback: insert
component_plugin_name: NodesPlugin
component_plugin_version: 26.1.0.dev4
e8e2df93-abc9-492a-9c0b-92c4a68895b9:
component_type: PluginVariableNode
id: e8e2df93-abc9-492a-9c0b-92c4a68895b9
name: read_var_step
description: ''
metadata:
__metadata_info__: {}
inputs: []
outputs:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
branches:
- next
input_mapping: {}
output_mapping: {}
write_variables: []
read_variables:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
write_operations: {}
component_plugin_name: NodesPlugin
component_plugin_version: 26.1.0.dev4
bd2331f9-c336-446d-b6e8-5c4365e4327b:
component_type: PluginOutputMessageNode
id: bd2331f9-c336-446d-b6e8-5c4365e4327b
name: output_step
description: ''
metadata:
__metadata_info__: {}
inputs:
- description: '"feedback" input variable for the template'
type: string
title: feedback
outputs:
- description: the message added to the messages list
type: string
title: output_message
branches:
- next
message: 'Collected feedback: {{ feedback }}'
input_mapping: {}
output_mapping: {}
message_type: AGENT
rephrase: false
llm_config: null
expose_message_as_output: true
component_plugin_name: NodesPlugin
component_plugin_version: 26.1.0.dev4
9834131e-83bf-4927-81bc-89965824271f:
component_type: EndNode
id: 9834131e-83bf-4927-81bc-89965824271f
name: None End node
description: End node representing all transitions to None in the WayFlow flow
metadata: {}
inputs:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
- description: the message added to the messages list
type: string
title: output_message
outputs:
- description: list of user feedback
type: array
items:
type: string
title: user_feedback
default: []
- description: the message added to the messages list
type: string
title: output_message
branches: []
branch_name: next
agentspec_version: 25.4.2
{
"component_type": "ExtendedFlow",
"id": "b41482ac-31b3-4117-805e-cb34931e9971",
"name": "flow_3fc1343f__auto",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"type": "string",
"title": "feedback_1"
},
{
"type": "string",
"title": "feedback_2"
}
],
"outputs": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
},
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
}
],
"start_node": {
"$component_ref": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b"
},
"nodes": [
{
"$component_ref": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b"
},
{
"$component_ref": "be27d2dc-0185-41b0-bbbc-31060306b34c"
},
{
"$component_ref": "4991b600-4fe1-4e46-82f8-6d0764989291"
},
{
"$component_ref": "e8e2df93-abc9-492a-9c0b-92c4a68895b9"
},
{
"$component_ref": "bd2331f9-c336-446d-b6e8-5c4365e4327b"
},
{
"$component_ref": "e139d3c9-66ca-4e0e-afd5-af41c0bbffd0"
}
],
"control_flow_connections": [
{
"component_type": "ControlFlowEdge",
"id": "c98164c9-eeaa-42da-9f42-c8e574b34c4a",
"name": "start_step_to_write_var_step_1_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b"
},
"from_branch": null,
"to_node": {
"$component_ref": "be27d2dc-0185-41b0-bbbc-31060306b34c"
}
},
{
"component_type": "ControlFlowEdge",
"id": "95b902ad-6e56-4587-9e92-d725c955f5b1",
"name": "write_var_step_1_to_write_var_step_2_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "be27d2dc-0185-41b0-bbbc-31060306b34c"
},
"from_branch": null,
"to_node": {
"$component_ref": "4991b600-4fe1-4e46-82f8-6d0764989291"
}
},
{
"component_type": "ControlFlowEdge",
"id": "57bafe45-a33c-44bc-a21a-51205da9a8d8",
"name": "write_var_step_2_to_read_var_step_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "4991b600-4fe1-4e46-82f8-6d0764989291"
},
"from_branch": null,
"to_node": {
"$component_ref": "e8e2df93-abc9-492a-9c0b-92c4a68895b9"
}
},
{
"component_type": "ControlFlowEdge",
"id": "621e214c-4048-409d-920d-7af0a09dd46a",
"name": "read_var_step_to_output_step_control_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"from_node": {
"$component_ref": "e8e2df93-abc9-492a-9c0b-92c4a68895b9"
},
"from_branch": null,
"to_node": {
"$component_ref": "bd2331f9-c336-446d-b6e8-5c4365e4327b"
}
},
{
"component_type": "ControlFlowEdge",
"id": "6484068a-3369-48d9-bf23-5192b3a805c1",
"name": "output_step_to_None End node_control_flow_edge",
"description": null,
"metadata": {},
"from_node": {
"$component_ref": "bd2331f9-c336-446d-b6e8-5c4365e4327b"
},
"from_branch": null,
"to_node": {
"$component_ref": "e139d3c9-66ca-4e0e-afd5-af41c0bbffd0"
}
}
],
"data_flow_connections": [
{
"component_type": "DataFlowEdge",
"id": "29904c9b-8ff3-410c-a484-d95a9f4f9248",
"name": "start_step_feedback_1_to_write_var_step_1_user_feedback_data_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"source_node": {
"$component_ref": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b"
},
"source_output": "feedback_1",
"destination_node": {
"$component_ref": "be27d2dc-0185-41b0-bbbc-31060306b34c"
},
"destination_input": "user_feedback"
},
{
"component_type": "DataFlowEdge",
"id": "5440b896-e11b-48b3-ae83-4e0832f87bc6",
"name": "start_step_feedback_2_to_write_var_step_2_user_feedback_data_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"source_node": {
"$component_ref": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b"
},
"source_output": "feedback_2",
"destination_node": {
"$component_ref": "4991b600-4fe1-4e46-82f8-6d0764989291"
},
"destination_input": "user_feedback"
},
{
"component_type": "DataFlowEdge",
"id": "ff59cde4-e95d-4caf-b8b3-0e9097013bb2",
"name": "read_var_step_user_feedback_to_output_step_feedback_data_flow_edge",
"description": null,
"metadata": {
"__metadata_info__": {}
},
"source_node": {
"$component_ref": "e8e2df93-abc9-492a-9c0b-92c4a68895b9"
},
"source_output": "user_feedback",
"destination_node": {
"$component_ref": "bd2331f9-c336-446d-b6e8-5c4365e4327b"
},
"destination_input": "feedback"
},
{
"component_type": "DataFlowEdge",
"id": "b3b923f5-5329-4c3c-aed6-a497f0709010",
"name": "read_var_step_user_feedback_to_None End node_user_feedback_data_flow_edge",
"description": null,
"metadata": {},
"source_node": {
"$component_ref": "e8e2df93-abc9-492a-9c0b-92c4a68895b9"
},
"source_output": "user_feedback",
"destination_node": {
"$component_ref": "e139d3c9-66ca-4e0e-afd5-af41c0bbffd0"
},
"destination_input": "user_feedback"
},
{
"component_type": "DataFlowEdge",
"id": "a4acc7e5-0def-494b-8721-b1d3a51bc46e",
"name": "output_step_output_message_to_None End node_output_message_data_flow_edge",
"description": null,
"metadata": {},
"source_node": {
"$component_ref": "bd2331f9-c336-446d-b6e8-5c4365e4327b"
},
"source_output": "output_message",
"destination_node": {
"$component_ref": "e139d3c9-66ca-4e0e-afd5-af41c0bbffd0"
},
"destination_input": "output_message"
}
],
"context_providers": [],
"state": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
}
],
"component_plugin_name": "FlowPlugin",
"component_plugin_version": "26.1.0.dev4",
"$referenced_components": {
"57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b": {
"component_type": "StartNode",
"id": "57f93e9d-9d58-4c7b-8d53-22f6d40b2a3b",
"name": "start_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"type": "string",
"title": "feedback_1"
},
{
"type": "string",
"title": "feedback_2"
}
],
"outputs": [
{
"type": "string",
"title": "feedback_1"
},
{
"type": "string",
"title": "feedback_2"
}
],
"branches": [
"next"
]
},
"be27d2dc-0185-41b0-bbbc-31060306b34c": {
"component_type": "PluginVariableNode",
"id": "be27d2dc-0185-41b0-bbbc-31060306b34c",
"name": "write_var_step_1",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"description": "list of user feedback (single element)",
"type": "string",
"title": "user_feedback"
}
],
"outputs": [],
"branches": [
"next"
],
"input_mapping": {},
"output_mapping": {},
"write_variables": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
}
],
"read_variables": [],
"write_operations": {
"user_feedback": "insert"
},
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "26.1.0.dev4"
},
"4991b600-4fe1-4e46-82f8-6d0764989291": {
"component_type": "PluginVariableNode",
"id": "4991b600-4fe1-4e46-82f8-6d0764989291",
"name": "write_var_step_2",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"description": "list of user feedback (single element)",
"type": "string",
"title": "user_feedback"
}
],
"outputs": [],
"branches": [
"next"
],
"input_mapping": {},
"output_mapping": {},
"write_variables": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
}
],
"read_variables": [],
"write_operations": {
"user_feedback": "insert"
},
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "26.1.0.dev4"
},
"e8e2df93-abc9-492a-9c0b-92c4a68895b9": {
"component_type": "PluginVariableNode",
"id": "e8e2df93-abc9-492a-9c0b-92c4a68895b9",
"name": "read_var_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [],
"outputs": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
}
],
"branches": [
"next"
],
"input_mapping": {},
"output_mapping": {},
"write_variables": [],
"read_variables": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
}
],
"write_operations": {},
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "26.1.0.dev4"
},
"bd2331f9-c336-446d-b6e8-5c4365e4327b": {
"component_type": "PluginOutputMessageNode",
"id": "bd2331f9-c336-446d-b6e8-5c4365e4327b",
"name": "output_step",
"description": "",
"metadata": {
"__metadata_info__": {}
},
"inputs": [
{
"description": "\"feedback\" input variable for the template",
"type": "string",
"title": "feedback"
}
],
"outputs": [
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
}
],
"branches": [
"next"
],
"message": "Collected feedback: {{ feedback }}",
"input_mapping": {},
"output_mapping": {},
"message_type": "AGENT",
"rephrase": false,
"llm_config": null,
"expose_message_as_output": true,
"component_plugin_name": "NodesPlugin",
"component_plugin_version": "26.1.0.dev4"
},
"e139d3c9-66ca-4e0e-afd5-af41c0bbffd0": {
"component_type": "EndNode",
"id": "e139d3c9-66ca-4e0e-afd5-af41c0bbffd0",
"name": "None End node",
"description": "End node representing all transitions to None in the WayFlow flow",
"metadata": {},
"inputs": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
},
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
}
],
"outputs": [
{
"description": "list of user feedback",
"type": "array",
"items": {
"type": "string"
},
"title": "user_feedback",
"default": []
},
{
"description": "the message added to the messages list",
"type": "string",
"title": "output_message"
}
],
"branches": [],
"branch_name": "next"
}
},
"agentspec_version": "25.4.2"
}
You can then load the configuration back to an assistant using the AgentSpecLoader.
from wayflowcore.agentspec import AgentSpecLoader
assistant: Flow = AgentSpecLoader().load_yaml(serialized_assistant)
Note
This guide uses the following extension/plugin Agent Spec components:
PluginReadVariableNodePluginWriteVariableNode
See the list of available Agent Spec extension/plugin components in the API Reference
Next steps#
Now that you have learned how to use Variables in Flows, you may proceed to FlowContextProvider to learn how to provide context for flow execution.
Full code#
Click on the card at the top of this page to download the full code for this guide or copy the code below.
1# Copyright © 2025, 2026 Oracle and/or its affiliates.
2#
3# This software is under the Apache License 2.0
4# %%[markdown]
5# Code Example - How to Use Variables for Shared State in Flows
6# -------------------------------------------------------------
7
8# How to use:
9# Create a new Python virtual environment and install the latest WayFlow version.
10# ```bash
11# python -m venv venv-wayflowcore
12# source venv-wayflowcore/bin/activate
13# pip install --upgrade pip
14# pip install "wayflowcore==26.2.0.dev0"
15# ```
16
17# You can now run the script
18# 1. As a Python file:
19# ```bash
20# python howto_variable.py
21# ```
22# 2. As a Notebook (in VSCode):
23# When viewing the file,
24# - press the keys Ctrl + Enter to run the selected cell
25# - or Shift + Enter to run the selected cell and move to the cell below# (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0) or Universal Permissive License
26# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl), at your option.
27
28
29
30# %%[markdown]
31## Define a Variable
32
33# %%
34from wayflowcore.variable import Variable
35from wayflowcore.property import ListProperty, StringProperty
36
37feedback_variable = Variable(
38 name="user_feedback",
39 type=ListProperty(item_type=StringProperty()),
40 description="list of user feedback",
41 default_value=[],
42)
43
44
45# %%[markdown]
46## Define Flow Steps
47
48# %%
49from wayflowcore.steps import StartStep, OutputMessageStep, VariableStep
50from wayflowcore.property import StringProperty
51from wayflowcore.variable import VariableWriteOperation
52
53FEEDBACK_1 = "feedback_1"
54FEEDBACK_2 = "feedback_2"
55
56start_step = StartStep(
57 name="start_step",
58 input_descriptors=[StringProperty(FEEDBACK_1), StringProperty(FEEDBACK_2)],
59)
60
61write_feedback_1 = VariableStep(
62 name="write_var_step_1",
63 write_variables=[feedback_variable],
64 write_operations=VariableWriteOperation.INSERT,
65)
66
67write_feedback_2 = VariableStep(
68 name="write_var_step_2",
69 write_variables=[feedback_variable],
70 write_operations=VariableWriteOperation.INSERT,
71)
72
73read_feedback = VariableStep(
74 name="read_var_step",
75 read_variables=[feedback_variable],
76)
77
78output_step = OutputMessageStep("Collected feedback: {{ feedback }}", name="output_step")
79
80
81# %%[markdown]
82## Define a Flow with variable
83
84# %%
85from wayflowcore.controlconnection import ControlFlowEdge
86from wayflowcore.dataconnection import DataFlowEdge
87from wayflowcore.flow import Flow
88
89flow = Flow(
90 begin_step=start_step,
91 control_flow_edges=[
92 ControlFlowEdge(start_step, write_feedback_1),
93 ControlFlowEdge(write_feedback_1, write_feedback_2),
94 ControlFlowEdge(write_feedback_2, read_feedback),
95 ControlFlowEdge(read_feedback, output_step),
96 ControlFlowEdge(output_step, None),
97 ],
98 data_flow_edges=[
99 DataFlowEdge(start_step, FEEDBACK_1, write_feedback_1, feedback_variable.name),
100 DataFlowEdge(start_step, FEEDBACK_2, write_feedback_2, feedback_variable.name),
101 DataFlowEdge(read_feedback, feedback_variable.name, output_step, "feedback"),
102 ],
103 variables=[feedback_variable],
104)
105
106
107# %%[markdown]
108## Execute flow
109
110# %%
111conv = flow.start_conversation(
112 inputs={
113 FEEDBACK_1: "Very good!",
114 FEEDBACK_2: "Need to improve!",
115 }
116)
117conv.execute()
118
119result = conv.get_last_message().content
120print(result)
121# >>> Collected feedback: ["Very good!", "Need to improve!"]
122
123
124# %%[markdown]
125## Export config to Agent Spec
126
127# %%
128from wayflowcore.agentspec import AgentSpecExporter
129
130serialized_assistant = AgentSpecExporter().to_yaml(flow)
131
132
133# %%[markdown]
134## Load Agent Spec config
135
136# %%
137from wayflowcore.agentspec import AgentSpecLoader
138
139assistant: Flow = AgentSpecLoader().load_yaml(serialized_assistant)