How to Serialize and Deserialize Flows and Agents#

python-icon Download Python Script

Python script/notebook for this guide.

Serialization and deserialization how-to script

Prerequisites

This guide assumes familiarity with:

Assistant serialization is a crucial feature in WayFlow that allows you to save and load Agents and Flows, making it easy to persist their configurations and reuse them as needed.

In this guide, you will learn how to:

  • Serialize a simple Agent or Flow and deserialize it back into an executable assistant.

  • Use serialization for more complex assistants using tools.

Serialization/deserialization of Agents and Flows in WayFlow

Saving and loading simple assistants#

This section shows you how to serialize and reload WayFlow Agents and Flows.

Flows#

Start by creating a simple Flow that takes a user question as input and responds using an LLM.

from wayflowcore.flow import Flow
from wayflowcore.property import StringProperty
from wayflowcore.steps import CompleteStep, OutputMessageStep, PromptExecutionStep, StartStep
from wayflowcore.controlconnection import ControlFlowEdge
from wayflowcore.dataconnection import DataFlowEdge

start_step = StartStep(input_descriptors=[StringProperty("user_question")], name="start_step")
llm_execution_step = PromptExecutionStep(
    prompt_template="You are a helpful assistant, please answer the user request:{{user_request}}",
    llm=llm,
    name="llm_execution_step",
)
output_step = OutputMessageStep(message_template="{{llm_answer}}", name="output_step")
complete_step = CompleteStep(name="complete_step")
flow = Flow(
    begin_step=start_step,
    control_flow_edges=[
        ControlFlowEdge(source_step=start_step, destination_step=llm_execution_step),
        ControlFlowEdge(source_step=llm_execution_step, destination_step=output_step),
        ControlFlowEdge(source_step=output_step, destination_step=complete_step),
    ],
    data_flow_edges=[
        DataFlowEdge(start_step, "user_question", llm_execution_step, "user_request"),
        DataFlowEdge(llm_execution_step, PromptExecutionStep.OUTPUT, output_step, "llm_answer"),
    ],
)

API Reference: Flow | PromptExecutionStep

Once you have built the flow, you can serialize it using the serialize helper function.

from wayflowcore.serialization import serialize

serialized_flow = serialize(flow)
# Then the serialized flow can be easily saved as a YAML file
# with open("flow_config.yaml", 'w') as f:
#     f.write(serialized_flow)

API Reference: serialize

Then, save the serialized flow as a regular text file.

To deserialize the flow configuration back, use the autodeserialize helper function.

from wayflowcore.serialization import autodeserialize

# The YAML representation can be loaded as follows
# with open("flow_config.yaml") as f:
#     serialized_flow = f.read()

serialized_flow = """
_component_type: Flow
_referenced_objects:
  controlflowedge/4440502672:
    destination_step:
      $ref: promptexecutionstep/4440501184
    source_branch: next
    source_step:
      $ref: startstep/4440501136
  controlflowedge/4440505648:
    destination_step: null
    source_branch: next
    source_step:
      $ref: outputmessagestep/4440505696
  controlflowedge/4440505888:
    destination_step:
      $ref: outputmessagestep/4440505696
    source_branch: next
    source_step:
      $ref: promptexecutionstep/4440501184
  dataflowedge/4440503008:
    destination_input: llm_answer
    destination_step:
      $ref: outputmessagestep/4440505696
    source_output: output
    source_step:
      $ref: promptexecutionstep/4440501184
  dataflowedge/4440504592:
    destination_input: user_request
    destination_step:
      $ref: promptexecutionstep/4440501184
    source_output: user_question
    source_step:
      $ref: startstep/4440501136
  outputmessagestep/4440505696:
    _component_type: Step
    input_descriptors:
    - $ref: stringproperty/4440504160
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4440503200
    output_mapping: {}
    step_args:
      input_descriptors:
      - _component_type: Property
        description: '"llm_answer" input variable for the template'
        title: llm_answer
        type: string
      input_mapping: {}
      llm: null
      message_template: '{{llm_answer}}'
      message_type: AGENT
      output_descriptors:
      - _component_type: Property
        description: the message added to the messages list
        title: output_message
        type: string
      output_mapping: {}
      rephrase: false
    step_cls: OutputMessageStep
  promptexecutionstep/4440501184:
    _component_type: Step
    input_descriptors:
    - $ref: stringproperty/4440502720
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4440501376
    output_mapping: {}
    step_args:
      generation_config: null
      input_descriptors:
      - _component_type: Property
        description: '"user_request" input variable for the template'
        title: user_request
        type: string
      input_mapping: {}
      llm:
        $ref: vllmmodel/4384406112
      output_descriptors:
      - _component_type: Property
        description: the generated text
        title: output
        type: string
      output_mapping: {}
      prompt_template: You are a helpful assistant, please answer the user request:{{user_request}}
    step_cls: PromptExecutionStep
  startstep/4440501136:
    _component_type: Step
    input_descriptors:
    - $ref: stringproperty/4384405872
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4384405872
    output_mapping: {}
    step_args:
      input_descriptors:
      - _component_type: Property
        title: user_question
        type: string
      input_mapping: {}
      output_descriptors:
      - _component_type: Property
        title: user_question
        type: string
      output_mapping: {}
    step_cls: StartStep
  stringproperty/4384405872:
    _component_type: Property
    title: user_question
    type: string
  stringproperty/4440501376:
    _component_type: Property
    description: the generated text
    title: output
    type: string
  stringproperty/4440502720:
    _component_type: Property
    description: '"user_request" input variable for the template'
    title: user_request
    type: string
  stringproperty/4440503200:
    _component_type: Property
    description: the message added to the messages list
    title: output_message
    type: string
  stringproperty/4440504160:
    _component_type: Property
    description: '"llm_answer" input variable for the template'
    title: llm_answer
    type: string
  vllmmodel/4384406112:
    _component_type: LlmModel
    generation_config: null
    host_port: LLAMA70B_API_URL
    model_id: LLAMA70B_MODEL_ID
    model_type: vllm
begin_step_name: start_step
control_flow_edges:
- $ref: controlflowedge/4440502672
- $ref: controlflowedge/4440505888
- $ref: controlflowedge/4440505648
data_flow_edges:
- $ref: dataflowedge/4440504592
- $ref: dataflowedge/4440503008
end_steps:
- null
steps:
  llm_execution_step:
    $ref: promptexecutionstep/4440501184
  output_step:
    $ref: outputmessagestep/4440505696
  start_step:
    $ref: startstep/4440501136
variables: []
""".strip()

deserialized_flow: Flow = autodeserialize(serialized_flow)

API Reference: autodeserialize

After deserialization, the flow is ready to execute like any other WayFlow assistant.

Note

The serialized configuration file contains all elements that compose the Flow. However, this file is not intended to be human-readable and should only be handled using the serialize and autodeserialize functions.

Agents#

Continue to building a simple conversational Agent that can answer user questions.

from wayflowcore.agent import Agent

agent = Agent(
    llm=llm,
    custom_instruction="You are a helpful assistant, please answer user requests",
)

API Reference: Agent

Once you have built the agent, you can serialize it using the serialize helper function.

from wayflowcore.serialization import serialize

serialized_agent = serialize(agent)
# Then the serialized agent can be easily saved as a YAML file
# with open("agent_config.yaml", 'w') as f:
#     f.write(serialized_agent)

API Reference: serialize

Then, save the serialized agent as a regular text file.

To deserialize the agent configuration back, use the autodeserialize helper function.

from wayflowcore.serialization import autodeserialize

# The YAML representation can be loaded as follows
# with open("agent_config.yaml") as f:
#     serialized_agent = f.read()

serialized_agent = """
_component_type: Agent
_referenced_objects:
  vllmmodel/4357290592:
    _component_type: LlmModel
    generation_config: null
    host_port: LLAMA70B_API_URL
    model_id: LLAMA70B_MODEL_ID
    model_type: vllm
agents: []
caller_input_mode: always
can_finish_conversation: false
context_providers: []
custom_instruction: You are a helpful assistant, please answer user requests
flows: []
initial_message: Hi! How can I help you?
input_descriptors: []
llm:
  $ref: vllmmodel/4357290592
max_iterations: 10
output_descriptors: []
tools: []
""".strip()
deserialized_agent: Agent = autodeserialize(serialized_agent)

API Reference: autodeserialize

Similar to the Flow example above, once deserialized, the agent is ready to execute like any other WayFlow assistant.

Saving and loading assistants equipped with tools#

In this more advanced example, you will build assistants that use WayFlow Tools (such as ServerTool). These assistants require additional code to deserialize them into executable assistants.

Flows#

Create a Flow that asks the user for an input text, counts the number of characters, and generates a message with the result.

from typing import Annotated

from wayflowcore.controlconnection import ControlFlowEdge
from wayflowcore.dataconnection import DataFlowEdge
from wayflowcore.steps import InputMessageStep, OutputMessageStep, ToolExecutionStep

# Step names
ASK_USER_FOR_TEXT_STEP = "ask_user_for_text_step"
EXECUTE_TOOL_STEP = "execute_tool_step"
OUTPUT_MESSAGE_STEP = "output_message_step"

# Tool
from wayflowcore.tools import tool

@tool
def count_characters(
    text: Annotated[str, "Text for which want compute the number of characters"],
) -> str:
    """Count the number of characters in the given text"""
    return str(len(text))

# Define the steps and the Flow
ask_user_for_text_step = InputMessageStep(
    message_template="Please enter the text to count the number of characters of",
    name="ask_user_for_text_step",
)
execute_tool_step = ToolExecutionStep(tool=count_characters, name="execute_tool_step")
output_message_step = OutputMessageStep(
    message_template="There are {{num_characters}} characters in the following text:\n{{input_text}}",
    name="output_message_step",
)
flow = Flow(
    begin_step=ask_user_for_text_step,
    control_flow_edges=[
        ControlFlowEdge(source_step=ask_user_for_text_step, destination_step=execute_tool_step),
        ControlFlowEdge(source_step=execute_tool_step, destination_step=output_message_step),
        ControlFlowEdge(source_step=output_message_step, destination_step=None),
    ],
    data_flow_edges=[
        DataFlowEdge(
            ask_user_for_text_step, InputMessageStep.USER_PROVIDED_INPUT, execute_tool_step, "text"
        ),
        DataFlowEdge(
            ask_user_for_text_step,
            InputMessageStep.USER_PROVIDED_INPUT,
            output_message_step,
            "input_text",
        ),
        DataFlowEdge(
            execute_tool_step, ToolExecutionStep.TOOL_OUTPUT, output_message_step, "num_characters"
        ),
        DataFlowEdge(
            ask_user_for_text_step, InputMessageStep.USER_PROVIDED_INPUT, execute_tool_step, "text"
        ),
        DataFlowEdge(
            ask_user_for_text_step,
            InputMessageStep.USER_PROVIDED_INPUT,
            output_message_step,
            "input_text",
        ),
        DataFlowEdge(
            execute_tool_step, ToolExecutionStep.TOOL_OUTPUT, output_message_step, "num_characters"
        ),
    ],
)
# We can serialize the flow as before
serialized_flow = serialize(flow)

API Reference: InputMessageStep | OutputMessageStep | ToolExecutionStep | ServerTool

Serialize your flow just like any other assistant.

To deserialize the flow, you need to provide context about the tool used in the original flow. This can be done using DeserializationContext.

from wayflowcore.serialization import autodeserialize
from wayflowcore.serialization.context import DeserializationContext

serialized_flow = """
_component_type: Flow
_referenced_objects:
  controlflowedge/4395505584:
    destination_step:
      $ref: toolexecutionstep/4395515664
    source_branch: next
    source_step:
      $ref: inputmessagestep/4395511296
  controlflowedge/4395506928:
    destination_step:
      $ref: outputmessagestep/4395511584
    source_branch: next
    source_step:
      $ref: toolexecutionstep/4395515664
  controlflowedge/4395514320:
    destination_step: null
    source_branch: next
    source_step:
      $ref: outputmessagestep/4395511584
  controlflowedge/4395514656:
    destination_step:
      $ref: inputmessagestep/4395511296
    source_branch: next
    source_step:
      $ref: startstep/4395515424
  dataflowedge/4395503760:
    destination_input: num_characters
    destination_step:
      $ref: outputmessagestep/4395511584
    source_output: tool_output
    source_step:
      $ref: toolexecutionstep/4395515664
  dataflowedge/4395510192:
    destination_input: input_text
    destination_step:
      $ref: outputmessagestep/4395511584
    source_output: user_provided_input
    source_step:
      $ref: inputmessagestep/4395511296
  dataflowedge/4395514032:
    destination_input: text
    destination_step:
      $ref: toolexecutionstep/4395515664
    source_output: user_provided_input
    source_step:
      $ref: inputmessagestep/4395511296
  inputmessagestep/4395511296:
    _component_type: Step
    input_descriptors: []
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4395512400
    output_mapping: {}
    step_args:
      input_descriptors: []
      input_mapping: {}
      llm: null
      message_template: Please enter the text to count the number of characters of
      output_descriptors:
      - _component_type: Property
        description: the input value provided by the user
        title: user_provided_input
        type: string
      output_mapping: {}
      rephrase: false
    step_cls: InputMessageStep
  outputmessagestep/4395511584:
    _component_type: Step
    input_descriptors:
    - $ref: stringproperty/4395506880
    - $ref: stringproperty/4395510000
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4395508896
    output_mapping: {}
    step_args:
      input_descriptors:
      - _component_type: Property
        description: '"input_text" input variable for the template'
        title: input_text
        type: string
      - _component_type: Property
        description: '"num_characters" input variable for the template'
        title: num_characters
        type: string
      input_mapping: {}
      llm: null
      message_template: 'There are {{num_characters}} characters in the following
        text:

        {{input_text}}'
      message_type: AGENT
      output_descriptors:
      - _component_type: Property
        description: the message added to the messages list
        title: output_message
        type: string
      output_mapping: {}
      rephrase: false
    step_cls: OutputMessageStep
  servertool/4401253344:
    __metadata_info__: {}
    _component_type: Tool
    description: Count the number of characters in the given text
    name: count_characters
    output:
      type: string
    parameters:
      text:
        description: Text for which want compute the number of characters
        title: Text
        type: string
    tool_type: server
  startstep/4395515424:
    _component_type: Step
    input_descriptors: []
    input_mapping: {}
    output_descriptors: []
    output_mapping: {}
    step_args:
      input_descriptors: []
      input_mapping: {}
      output_descriptors: []
      output_mapping: {}
    step_cls: StartStep
  stringproperty/4395506160:
    _component_type: Property
    title: tool_output
    type: string
  stringproperty/4395506208:
    _component_type: Property
    description: Text for which want compute the number of characters
    title: text
    type: string
  stringproperty/4395506880:
    _component_type: Property
    description: '"input_text" input variable for the template'
    title: input_text
    type: string
  stringproperty/4395508896:
    _component_type: Property
    description: the message added to the messages list
    title: output_message
    type: string
  stringproperty/4395510000:
    _component_type: Property
    description: '"num_characters" input variable for the template'
    title: num_characters
    type: string
  stringproperty/4395512400:
    _component_type: Property
    description: the input value provided by the user
    title: user_provided_input
    type: string
  toolexecutionstep/4395515664:
    _component_type: Step
    input_descriptors:
    - $ref: stringproperty/4395506208
    input_mapping: {}
    output_descriptors:
    - $ref: stringproperty/4395506160
    output_mapping: {}
    step_args:
      input_descriptors:
      - _component_type: Property
        description: Text for which want compute the number of characters
        title: text
        type: string
      input_mapping: {}
      output_descriptors:
      - _component_type: Property
        title: tool_output
        type: string
      output_mapping: {}
      raise_exceptions: false
      tool:
        $ref: servertool/4401253344
    step_cls: ToolExecutionStep
begin_step_name: __StartStep__
control_flow_edges:
- $ref: controlflowedge/4395505584
- $ref: controlflowedge/4395506928
- $ref: controlflowedge/4395514320
- $ref: controlflowedge/4395514656
data_flow_edges:
- $ref: dataflowedge/4395514032
- $ref: dataflowedge/4395510192
- $ref: dataflowedge/4395503760
end_steps:
- null
steps:
  __StartStep__:
    $ref: startstep/4395515424
  ask_user_for_text_step:
    $ref: inputmessagestep/4395511296
  execute_tool_step:
    $ref: toolexecutionstep/4395515664
  output_message_step:
    $ref: outputmessagestep/4395511584
variables: []
""".strip()

deserialization_context = DeserializationContext()
deserialization_context.registered_tools[count_characters.name] = count_characters
deserialized_flow: Flow = autodeserialize(serialized_flow, deserialization_context)

After registering the tool in the dictionary of tools, pass the deserialization context to the autodeserialize function to deserialize the flow.

Important

Ensure that tool names in DeserializationContext.registered_tools are unique to avoid conflicts.

Agents#

Create an Agent that can access a tool to count the number of characters in a given text (this agent is equivalent to the flow example above).

from wayflowcore.tools import tool

# Tool
@tool
def count_characters(
    text: Annotated[str, "Text for which want compute the number of characters"],
) -> str:
    """Count the number of characters in the given text"""
    return str(len(text))

agent = Agent(
    llm=llm,
    tools=[count_characters],
    custom_instruction="You are a helpful assistant, please answer user requests",
)
serialized_agent = serialize(agent)

API Reference: ServerTool

Serialize your agent just like any other assistant.

Similar to the Flow example, deserializing the agent requires providing context about the tool used in the original agent. This can be done using DeserializationContext.

from wayflowcore.serialization import autodeserialize
from wayflowcore.serialization.context import DeserializationContext

serialized_agent = """
_component_type: Agent
_referenced_objects:
  servertool/4443551104:
    __metadata_info__: {}
    _component_type: Tool
    description: Count the number of characters in the given text
    name: count_characters
    output:
      type: string
    parameters:
      text:
        description: Text for which want compute the number of characters
        title: Text
        type: string
    tool_type: server
  vllmmodel/4426025136:
    _component_type: LlmModel
    generation_config: null
    host_port: LLAMA70B_API_URL
    model_id: LLAMA70B_MODEL_ID
    model_type: vllm
agents: []
caller_input_mode: always
can_finish_conversation: false
context_providers: []
custom_instruction: You are a helpful assistant, please answer user requests
flows: []
initial_message: Hi! How can I help you?
llm:
  $ref: vllmmodel/4426025136
max_iterations: 10
outputs: null
tools:
- $ref: servertool/4443551104
""".strip()

deserialization_context = DeserializationContext()
deserialization_context.registered_tools[count_characters.name] = count_characters
deserialized_agent: Agent = autodeserialize(serialized_agent, deserialization_context)

After registering the tool in the dictionary of tools, pass the deserialization context to the autodeserialize function to deserialize the agent.

Important

Ensure that tool names in DeserializationContext.registered_tools are unique to avoid conflicts.

Agent Spec Exporting/Loading#

You can export the flow or agent configuration to its Agent Spec configuration using the AgentSpecExporter.

from wayflowcore.agentspec import AgentSpecExporter

config_flow = AgentSpecExporter().to_json(flow)
config_agent = AgentSpecExporter().to_json(agent)

And load it back using the AgentSpecLoader.

from wayflowcore.agentspec import AgentSpecLoader

new_flow = AgentSpecLoader(tool_registry={"count_characters": count_characters}).load_json(
    config_flow
)
new_agent = AgentSpecLoader(tool_registry={"count_characters": count_characters}).load_json(
    config_agent
)

Recap#

In this guide, you learned how to serialize WayFlow Agents and Flows, as well as how to handle deserialization for assistants that use tools.

Next steps#

Having learned how to serialize and deserialize assistants built with WayFlow, you may now proceed to:

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 Oracle and/or its affiliates.
  2#
  3# This software is under the Universal Permissive License
  4# %%[markdown]
  5# Code Example - How to Serialize and Deserialize Components
  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.1" 
 15# ```
 16
 17# You can now run the script
 18# 1. As a Python file:
 19# ```bash
 20# python howto_serdeser.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# (UPL) 1.0 (LICENSE-UPL or https://oss.oracle.com/licenses/upl) or Apache License
 26# 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0), at your option.
 27
 28
 29
 30# %%[markdown]
 31## Configure LLM
 32
 33# %%
 34from wayflowcore.models import VllmModel
 35
 36llm = VllmModel(
 37    model_id="LLAMA_MODEL_ID",
 38    host_port="LLAMA_API_URL",
 39)
 40
 41# %%[markdown]
 42## Simple Flow Creation
 43
 44# %%
 45from wayflowcore.flow import Flow
 46from wayflowcore.property import StringProperty
 47from wayflowcore.steps import CompleteStep, OutputMessageStep, PromptExecutionStep, StartStep
 48from wayflowcore.controlconnection import ControlFlowEdge
 49from wayflowcore.dataconnection import DataFlowEdge
 50
 51start_step = StartStep(input_descriptors=[StringProperty("user_question")], name="start_step")
 52llm_execution_step = PromptExecutionStep(
 53    prompt_template="You are a helpful assistant, please answer the user request:{{user_request}}",
 54    llm=llm,
 55    name="llm_execution_step",
 56)
 57output_step = OutputMessageStep(message_template="{{llm_answer}}", name="output_step")
 58complete_step = CompleteStep(name="complete_step")
 59flow = Flow(
 60    begin_step=start_step,
 61    control_flow_edges=[
 62        ControlFlowEdge(source_step=start_step, destination_step=llm_execution_step),
 63        ControlFlowEdge(source_step=llm_execution_step, destination_step=output_step),
 64        ControlFlowEdge(source_step=output_step, destination_step=complete_step),
 65    ],
 66    data_flow_edges=[
 67        DataFlowEdge(start_step, "user_question", llm_execution_step, "user_request"),
 68        DataFlowEdge(llm_execution_step, PromptExecutionStep.OUTPUT, output_step, "llm_answer"),
 69    ],
 70)
 71
 72# %%[markdown]
 73## Simple Flow Serialization
 74
 75# %%
 76from wayflowcore.serialization import serialize
 77
 78serialized_flow = serialize(flow)
 79# Then the serialized flow can be easily saved as a YAML file
 80# with open("flow_config.yaml", 'w') as f:
 81#     f.write(serialized_flow)
 82
 83# %%[markdown]
 84## Simple Flow Deserialization
 85
 86# %%
 87from wayflowcore.serialization import autodeserialize
 88
 89# The YAML representation can be loaded as follows
 90# with open("flow_config.yaml") as f:
 91#     serialized_flow = f.read()
 92
 93serialized_flow = """
 94_component_type: Flow
 95_referenced_objects:
 96  controlflowedge/4440502672:
 97    destination_step:
 98      $ref: promptexecutionstep/4440501184
 99    source_branch: next
100    source_step:
101      $ref: startstep/4440501136
102  controlflowedge/4440505648:
103    destination_step: null
104    source_branch: next
105    source_step:
106      $ref: outputmessagestep/4440505696
107  controlflowedge/4440505888:
108    destination_step:
109      $ref: outputmessagestep/4440505696
110    source_branch: next
111    source_step:
112      $ref: promptexecutionstep/4440501184
113  dataflowedge/4440503008:
114    destination_input: llm_answer
115    destination_step:
116      $ref: outputmessagestep/4440505696
117    source_output: output
118    source_step:
119      $ref: promptexecutionstep/4440501184
120  dataflowedge/4440504592:
121    destination_input: user_request
122    destination_step:
123      $ref: promptexecutionstep/4440501184
124    source_output: user_question
125    source_step:
126      $ref: startstep/4440501136
127  outputmessagestep/4440505696:
128    _component_type: Step
129    input_descriptors:
130    - $ref: stringproperty/4440504160
131    input_mapping: {}
132    output_descriptors:
133    - $ref: stringproperty/4440503200
134    output_mapping: {}
135    step_args:
136      input_descriptors:
137      - _component_type: Property
138        description: '"llm_answer" input variable for the template'
139        title: llm_answer
140        type: string
141      input_mapping: {}
142      llm: null
143      message_template: '{{llm_answer}}'
144      message_type: AGENT
145      output_descriptors:
146      - _component_type: Property
147        description: the message added to the messages list
148        title: output_message
149        type: string
150      output_mapping: {}
151      rephrase: false
152    step_cls: OutputMessageStep
153  promptexecutionstep/4440501184:
154    _component_type: Step
155    input_descriptors:
156    - $ref: stringproperty/4440502720
157    input_mapping: {}
158    output_descriptors:
159    - $ref: stringproperty/4440501376
160    output_mapping: {}
161    step_args:
162      generation_config: null
163      input_descriptors:
164      - _component_type: Property
165        description: '"user_request" input variable for the template'
166        title: user_request
167        type: string
168      input_mapping: {}
169      llm:
170        $ref: vllmmodel/4384406112
171      output_descriptors:
172      - _component_type: Property
173        description: the generated text
174        title: output
175        type: string
176      output_mapping: {}
177      prompt_template: You are a helpful assistant, please answer the user request:{{user_request}}
178    step_cls: PromptExecutionStep
179  startstep/4440501136:
180    _component_type: Step
181    input_descriptors:
182    - $ref: stringproperty/4384405872
183    input_mapping: {}
184    output_descriptors:
185    - $ref: stringproperty/4384405872
186    output_mapping: {}
187    step_args:
188      input_descriptors:
189      - _component_type: Property
190        title: user_question
191        type: string
192      input_mapping: {}
193      output_descriptors:
194      - _component_type: Property
195        title: user_question
196        type: string
197      output_mapping: {}
198    step_cls: StartStep
199  stringproperty/4384405872:
200    _component_type: Property
201    title: user_question
202    type: string
203  stringproperty/4440501376:
204    _component_type: Property
205    description: the generated text
206    title: output
207    type: string
208  stringproperty/4440502720:
209    _component_type: Property
210    description: '"user_request" input variable for the template'
211    title: user_request
212    type: string
213  stringproperty/4440503200:
214    _component_type: Property
215    description: the message added to the messages list
216    title: output_message
217    type: string
218  stringproperty/4440504160:
219    _component_type: Property
220    description: '"llm_answer" input variable for the template'
221    title: llm_answer
222    type: string
223  vllmmodel/4384406112:
224    _component_type: LlmModel
225    generation_config: null
226    host_port: LLAMA70B_API_URL
227    model_id: LLAMA70B_MODEL_ID
228    model_type: vllm
229begin_step_name: start_step
230control_flow_edges:
231- $ref: controlflowedge/4440502672
232- $ref: controlflowedge/4440505888
233- $ref: controlflowedge/4440505648
234data_flow_edges:
235- $ref: dataflowedge/4440504592
236- $ref: dataflowedge/4440503008
237end_steps:
238- null
239steps:
240  llm_execution_step:
241    $ref: promptexecutionstep/4440501184
242  output_step:
243    $ref: outputmessagestep/4440505696
244  start_step:
245    $ref: startstep/4440501136
246variables: []
247""".strip()
248
249deserialized_flow: Flow = autodeserialize(serialized_flow)
250
251# %%[markdown]
252## Simple Agent Creation
253
254# %%
255from wayflowcore.agent import Agent
256
257agent = Agent(
258    llm=llm,
259    custom_instruction="You are a helpful assistant, please answer user requests",
260)
261
262# %%[markdown]
263## Simple Agent Serialization
264
265# %%
266from wayflowcore.serialization import serialize
267
268serialized_agent = serialize(agent)
269# Then the serialized agent can be easily saved as a YAML file
270# with open("agent_config.yaml", 'w') as f:
271#     f.write(serialized_agent)
272
273# %%[markdown]
274## Simple Agent Deserialization
275
276# %%
277from wayflowcore.serialization import autodeserialize
278
279# The YAML representation can be loaded as follows
280# with open("agent_config.yaml") as f:
281#     serialized_agent = f.read()
282
283serialized_agent = """
284_component_type: Agent
285_referenced_objects:
286  vllmmodel/4357290592:
287    _component_type: LlmModel
288    generation_config: null
289    host_port: LLAMA70B_API_URL
290    model_id: LLAMA70B_MODEL_ID
291    model_type: vllm
292agents: []
293caller_input_mode: always
294can_finish_conversation: false
295context_providers: []
296custom_instruction: You are a helpful assistant, please answer user requests
297flows: []
298initial_message: Hi! How can I help you?
299input_descriptors: []
300llm:
301  $ref: vllmmodel/4357290592
302max_iterations: 10
303output_descriptors: []
304tools: []
305""".strip()
306deserialized_agent: Agent = autodeserialize(serialized_agent)
307
308
309# %%[markdown]
310## Complex Flow Creation
311
312# %%
313from typing import Annotated
314
315from wayflowcore.controlconnection import ControlFlowEdge
316from wayflowcore.dataconnection import DataFlowEdge
317from wayflowcore.steps import InputMessageStep, OutputMessageStep, ToolExecutionStep
318
319# Step names
320ASK_USER_FOR_TEXT_STEP = "ask_user_for_text_step"
321EXECUTE_TOOL_STEP = "execute_tool_step"
322OUTPUT_MESSAGE_STEP = "output_message_step"
323
324# Tool
325from wayflowcore.tools import tool
326
327@tool
328def count_characters(
329    text: Annotated[str, "Text for which want compute the number of characters"],
330) -> str:
331    """Count the number of characters in the given text"""
332    return str(len(text))
333
334# Define the steps and the Flow
335ask_user_for_text_step = InputMessageStep(
336    message_template="Please enter the text to count the number of characters of",
337    name="ask_user_for_text_step",
338)
339execute_tool_step = ToolExecutionStep(tool=count_characters, name="execute_tool_step")
340output_message_step = OutputMessageStep(
341    message_template="There are {{num_characters}} characters in the following text:\n{{input_text}}",
342    name="output_message_step",
343)
344flow = Flow(
345    begin_step=ask_user_for_text_step,
346    control_flow_edges=[
347        ControlFlowEdge(source_step=ask_user_for_text_step, destination_step=execute_tool_step),
348        ControlFlowEdge(source_step=execute_tool_step, destination_step=output_message_step),
349        ControlFlowEdge(source_step=output_message_step, destination_step=None),
350    ],
351    data_flow_edges=[
352        DataFlowEdge(
353            ask_user_for_text_step, InputMessageStep.USER_PROVIDED_INPUT, execute_tool_step, "text"
354        ),
355        DataFlowEdge(
356            ask_user_for_text_step,
357            InputMessageStep.USER_PROVIDED_INPUT,
358            output_message_step,
359            "input_text",
360        ),
361        DataFlowEdge(
362            execute_tool_step, ToolExecutionStep.TOOL_OUTPUT, output_message_step, "num_characters"
363        ),
364        DataFlowEdge(
365            ask_user_for_text_step, InputMessageStep.USER_PROVIDED_INPUT, execute_tool_step, "text"
366        ),
367        DataFlowEdge(
368            ask_user_for_text_step,
369            InputMessageStep.USER_PROVIDED_INPUT,
370            output_message_step,
371            "input_text",
372        ),
373        DataFlowEdge(
374            execute_tool_step, ToolExecutionStep.TOOL_OUTPUT, output_message_step, "num_characters"
375        ),
376    ],
377)
378# We can serialize the flow as before
379serialized_flow = serialize(flow)
380
381# %%[markdown]
382## Complex Flow Deserialization
383
384# %%
385from wayflowcore.serialization import autodeserialize
386from wayflowcore.serialization.context import DeserializationContext
387
388serialized_flow = """
389_component_type: Flow
390_referenced_objects:
391  controlflowedge/4395505584:
392    destination_step:
393      $ref: toolexecutionstep/4395515664
394    source_branch: next
395    source_step:
396      $ref: inputmessagestep/4395511296
397  controlflowedge/4395506928:
398    destination_step:
399      $ref: outputmessagestep/4395511584
400    source_branch: next
401    source_step:
402      $ref: toolexecutionstep/4395515664
403  controlflowedge/4395514320:
404    destination_step: null
405    source_branch: next
406    source_step:
407      $ref: outputmessagestep/4395511584
408  controlflowedge/4395514656:
409    destination_step:
410      $ref: inputmessagestep/4395511296
411    source_branch: next
412    source_step:
413      $ref: startstep/4395515424
414  dataflowedge/4395503760:
415    destination_input: num_characters
416    destination_step:
417      $ref: outputmessagestep/4395511584
418    source_output: tool_output
419    source_step:
420      $ref: toolexecutionstep/4395515664
421  dataflowedge/4395510192:
422    destination_input: input_text
423    destination_step:
424      $ref: outputmessagestep/4395511584
425    source_output: user_provided_input
426    source_step:
427      $ref: inputmessagestep/4395511296
428  dataflowedge/4395514032:
429    destination_input: text
430    destination_step:
431      $ref: toolexecutionstep/4395515664
432    source_output: user_provided_input
433    source_step:
434      $ref: inputmessagestep/4395511296
435  inputmessagestep/4395511296:
436    _component_type: Step
437    input_descriptors: []
438    input_mapping: {}
439    output_descriptors:
440    - $ref: stringproperty/4395512400
441    output_mapping: {}
442    step_args:
443      input_descriptors: []
444      input_mapping: {}
445      llm: null
446      message_template: Please enter the text to count the number of characters of
447      output_descriptors:
448      - _component_type: Property
449        description: the input value provided by the user
450        title: user_provided_input
451        type: string
452      output_mapping: {}
453      rephrase: false
454    step_cls: InputMessageStep
455  outputmessagestep/4395511584:
456    _component_type: Step
457    input_descriptors:
458    - $ref: stringproperty/4395506880
459    - $ref: stringproperty/4395510000
460    input_mapping: {}
461    output_descriptors:
462    - $ref: stringproperty/4395508896
463    output_mapping: {}
464    step_args:
465      input_descriptors:
466      - _component_type: Property
467        description: '"input_text" input variable for the template'
468        title: input_text
469        type: string
470      - _component_type: Property
471        description: '"num_characters" input variable for the template'
472        title: num_characters
473        type: string
474      input_mapping: {}
475      llm: null
476      message_template: 'There are {{num_characters}} characters in the following
477        text:
478
479        {{input_text}}'
480      message_type: AGENT
481      output_descriptors:
482      - _component_type: Property
483        description: the message added to the messages list
484        title: output_message
485        type: string
486      output_mapping: {}
487      rephrase: false
488    step_cls: OutputMessageStep
489  servertool/4401253344:
490    __metadata_info__: {}
491    _component_type: Tool
492    description: Count the number of characters in the given text
493    name: count_characters
494    output:
495      type: string
496    parameters:
497      text:
498        description: Text for which want compute the number of characters
499        title: Text
500        type: string
501    tool_type: server
502  startstep/4395515424:
503    _component_type: Step
504    input_descriptors: []
505    input_mapping: {}
506    output_descriptors: []
507    output_mapping: {}
508    step_args:
509      input_descriptors: []
510      input_mapping: {}
511      output_descriptors: []
512      output_mapping: {}
513    step_cls: StartStep
514  stringproperty/4395506160:
515    _component_type: Property
516    title: tool_output
517    type: string
518  stringproperty/4395506208:
519    _component_type: Property
520    description: Text for which want compute the number of characters
521    title: text
522    type: string
523  stringproperty/4395506880:
524    _component_type: Property
525    description: '"input_text" input variable for the template'
526    title: input_text
527    type: string
528  stringproperty/4395508896:
529    _component_type: Property
530    description: the message added to the messages list
531    title: output_message
532    type: string
533  stringproperty/4395510000:
534    _component_type: Property
535    description: '"num_characters" input variable for the template'
536    title: num_characters
537    type: string
538  stringproperty/4395512400:
539    _component_type: Property
540    description: the input value provided by the user
541    title: user_provided_input
542    type: string
543  toolexecutionstep/4395515664:
544    _component_type: Step
545    input_descriptors:
546    - $ref: stringproperty/4395506208
547    input_mapping: {}
548    output_descriptors:
549    - $ref: stringproperty/4395506160
550    output_mapping: {}
551    step_args:
552      input_descriptors:
553      - _component_type: Property
554        description: Text for which want compute the number of characters
555        title: text
556        type: string
557      input_mapping: {}
558      output_descriptors:
559      - _component_type: Property
560        title: tool_output
561        type: string
562      output_mapping: {}
563      raise_exceptions: false
564      tool:
565        $ref: servertool/4401253344
566    step_cls: ToolExecutionStep
567begin_step_name: __StartStep__
568control_flow_edges:
569- $ref: controlflowedge/4395505584
570- $ref: controlflowedge/4395506928
571- $ref: controlflowedge/4395514320
572- $ref: controlflowedge/4395514656
573data_flow_edges:
574- $ref: dataflowedge/4395514032
575- $ref: dataflowedge/4395510192
576- $ref: dataflowedge/4395503760
577end_steps:
578- null
579steps:
580  __StartStep__:
581    $ref: startstep/4395515424
582  ask_user_for_text_step:
583    $ref: inputmessagestep/4395511296
584  execute_tool_step:
585    $ref: toolexecutionstep/4395515664
586  output_message_step:
587    $ref: outputmessagestep/4395511584
588variables: []
589""".strip()
590
591deserialization_context = DeserializationContext()
592deserialization_context.registered_tools[count_characters.name] = count_characters
593deserialized_flow: Flow = autodeserialize(serialized_flow, deserialization_context)
594
595# %%[markdown]
596## Complex Agent Creation
597
598# %%
599from wayflowcore.tools import tool
600
601# Tool
602@tool
603def count_characters(
604    text: Annotated[str, "Text for which want compute the number of characters"],
605) -> str:
606    """Count the number of characters in the given text"""
607    return str(len(text))
608
609agent = Agent(
610    llm=llm,
611    tools=[count_characters],
612    custom_instruction="You are a helpful assistant, please answer user requests",
613)
614serialized_agent = serialize(agent)
615
616# %%[markdown]
617## Complex Agent Deserialization
618
619# %%
620from wayflowcore.serialization import autodeserialize
621from wayflowcore.serialization.context import DeserializationContext
622
623serialized_agent = """
624_component_type: Agent
625_referenced_objects:
626  servertool/4443551104:
627    __metadata_info__: {}
628    _component_type: Tool
629    description: Count the number of characters in the given text
630    name: count_characters
631    output:
632      type: string
633    parameters:
634      text:
635        description: Text for which want compute the number of characters
636        title: Text
637        type: string
638    tool_type: server
639  vllmmodel/4426025136:
640    _component_type: LlmModel
641    generation_config: null
642    host_port: LLAMA70B_API_URL
643    model_id: LLAMA70B_MODEL_ID
644    model_type: vllm
645agents: []
646caller_input_mode: always
647can_finish_conversation: false
648context_providers: []
649custom_instruction: You are a helpful assistant, please answer user requests
650flows: []
651initial_message: Hi! How can I help you?
652llm:
653  $ref: vllmmodel/4426025136
654max_iterations: 10
655outputs: null
656tools:
657- $ref: servertool/4443551104
658""".strip()
659
660deserialization_context = DeserializationContext()
661deserialization_context.registered_tools[count_characters.name] = count_characters
662deserialized_agent: Agent = autodeserialize(serialized_agent, deserialization_context)
663
664# %%[markdown]
665## Export Config to Agent Spec
666
667# %%
668from wayflowcore.agentspec import AgentSpecExporter
669
670config_flow = AgentSpecExporter().to_json(flow)
671config_agent = AgentSpecExporter().to_json(agent)
672
673# %%[markdown]
674## Load Agent Spec Config
675
676# %%
677from wayflowcore.agentspec import AgentSpecLoader
678
679new_flow = AgentSpecLoader(tool_registry={"count_characters": count_characters}).load_json(
680    config_flow
681)
682new_agent = AgentSpecLoader(tool_registry={"count_characters": count_characters}).load_json(
683    config_agent
684)